mbox series

[v4,0/2] Clean up min_buffers_needed misusages

Message ID 20231211133251.150999-1-benjamin.gaignard@collabora.com
Headers show
Series Clean up min_buffers_needed misusages | expand

Message

Benjamin Gaignard Dec. 11, 2023, 1:32 p.m. UTC
This series implement Hans's RFC: https://www.spinics.net/lists/linux-media/msg244455.html

To summarize Hans's proposal it is needed to distinguish two cases:
- the minimal number of buffers to be allocated when calling
  VIDIOC_REQBUFS.
- the minimale number of queued buffers before start streaming.
Until now drivers use vb2_queue min_buffers_needed field in the both
cases but before introduce delete buffers we need to clarify for which
usage each of them use min_buffers_needed field.

The branch with all patches is here:
https://gitlab.collabora.com/benjamin.gaignard/for-upstream/-/commits/clean_min_need_buffers_v5

I have tested with this command line, I haven't notice issues:
./test-media -kmemleak mc

changes in version 5:
- Fix the comments done by Hans:
  Rework comments on videobuf2-core.h
  Add checks in vb2_core_queue_init().
- Patch test-drivers to use min_reqbufs_allocation field.

changes in version 4:
- restore removed lines in zoran and vdec drivers.

changes in version 3:
- Just rename min_buffers_needed into min_queued_buffers everywhere
  without trying to fix the drivers.
- Introduce min_reqbufs_allocation field to be used when calling VIDIOC_REQBUFS.

changes in version 2:
- change min_buffers_needed into min_queues_buffers instead of min_dma_buffers_needed
- patches order
- only one patch to rename min_buffers_needed into min_queues_buffer

Benjamin Gaignard (3):
  videobuf2: core: Rename min_buffers_needed field to vb2_queue
  videobuf2: Add min_reqbufs_allocation field to vb2_queue structure
  media: test-drivers: Set REQBUFS minimum number of buffers

 drivers/input/touchscreen/atmel_mxt_ts.c      |  2 +-
 drivers/input/touchscreen/sur40.c             |  2 +-
 drivers/media/common/saa7146/saa7146_fops.c   |  2 +-
 .../media/common/videobuf2/videobuf2-core.c   | 34 +++++++++++--------
 drivers/media/dvb-core/dvb_vb2.c              |  2 +-
 drivers/media/i2c/video-i2c.c                 |  2 +-
 drivers/media/pci/bt8xx/bttv-driver.c         |  2 +-
 drivers/media/pci/cobalt/cobalt-v4l2.c        |  2 +-
 drivers/media/pci/cx18/cx18-streams.c         |  2 +-
 drivers/media/pci/cx23885/cx23885-417.c       |  2 +-
 drivers/media/pci/cx23885/cx23885-dvb.c       |  2 +-
 drivers/media/pci/cx23885/cx23885-video.c     |  4 +--
 drivers/media/pci/cx25821/cx25821-video.c     |  2 +-
 drivers/media/pci/cx88/cx88-blackbird.c       |  2 +-
 drivers/media/pci/cx88/cx88-dvb.c             |  2 +-
 drivers/media/pci/cx88/cx88-video.c           |  4 +--
 drivers/media/pci/dt3155/dt3155.c             |  2 +-
 drivers/media/pci/intel/ipu3/ipu3-cio2.c      |  2 +-
 drivers/media/pci/mgb4/mgb4_vin.c             |  2 +-
 drivers/media/pci/mgb4/mgb4_vout.c            |  2 +-
 drivers/media/pci/tw5864/tw5864-video.c       |  2 +-
 drivers/media/pci/tw68/tw68-video.c           |  2 +-
 drivers/media/pci/tw686x/tw686x-video.c       |  2 +-
 drivers/media/pci/zoran/zoran_driver.c        |  6 ++--
 drivers/media/platform/amphion/vpu_v4l2.c     |  4 +--
 drivers/media/platform/aspeed/aspeed-video.c  |  2 +-
 drivers/media/platform/atmel/atmel-isi.c      |  2 +-
 .../platform/chips-media/coda/coda-common.c   |  2 +-
 .../platform/microchip/microchip-isc-base.c   |  2 +-
 drivers/media/platform/nuvoton/npcm-video.c   |  2 +-
 drivers/media/platform/nxp/imx7-media-csi.c   |  2 +-
 .../platform/nxp/imx8-isi/imx8-isi-video.c    |  2 +-
 drivers/media/platform/qcom/venus/vdec.c      |  4 +--
 drivers/media/platform/qcom/venus/venc.c      |  4 +--
 .../platform/renesas/rcar-vin/rcar-dma.c      |  2 +-
 drivers/media/platform/renesas/renesas-ceu.c  |  2 +-
 .../platform/renesas/rzg2l-cru/rzg2l-video.c  |  2 +-
 drivers/media/platform/renesas/sh_vou.c       |  2 +-
 .../platform/rockchip/rkisp1/rkisp1-capture.c |  2 +-
 drivers/media/platform/st/sti/hva/hva-v4l2.c  |  4 +--
 drivers/media/platform/st/stm32/stm32-dcmi.c  |  2 +-
 .../st/stm32/stm32-dcmipp/dcmipp-bytecap.c    |  4 +--
 .../platform/sunxi/sun4i-csi/sun4i_dma.c      |  2 +-
 .../sunxi/sun6i-csi/sun6i_csi_capture.c       |  2 +-
 .../media/platform/sunxi/sun8i-di/sun8i-di.c  |  4 +--
 .../sunxi/sun8i-rotate/sun8i_rotate.c         |  4 +--
 .../media/platform/ti/am437x/am437x-vpfe.c    |  2 +-
 drivers/media/platform/ti/cal/cal-video.c     |  2 +-
 .../media/platform/ti/davinci/vpif_capture.c  |  2 +-
 .../media/platform/ti/davinci/vpif_display.c  |  2 +-
 .../platform/ti/j721e-csi2rx/j721e-csi2rx.c   |  2 +-
 drivers/media/platform/ti/omap/omap_vout.c    |  2 +-
 .../media/test-drivers/vimc/vimc-capture.c    |  2 +-
 drivers/media/test-drivers/vivid/vivid-core.c |  4 +--
 drivers/media/usb/cx231xx/cx231xx-417.c       |  2 +-
 drivers/media/usb/cx231xx/cx231xx-video.c     |  4 +--
 drivers/media/usb/dvb-usb/cxusb-analog.c      |  2 +-
 drivers/media/usb/gspca/gspca.c               |  6 ++--
 .../media/deprecated/atmel/atmel-isc-base.c   |  2 +-
 drivers/staging/media/imx/imx-media-capture.c |  2 +-
 drivers/staging/media/ipu3/ipu3-v4l2.c        |  2 +-
 drivers/staging/media/meson/vdec/vdec.c       |  6 ++--
 .../staging/media/starfive/camss/stf-video.c  |  2 +-
 .../media/sunxi/sun6i-isp/sun6i_isp_capture.c |  2 +-
 .../media/sunxi/sun6i-isp/sun6i_isp_params.c  |  2 +-
 drivers/staging/media/tegra-video/vi.c        |  2 +-
 include/media/videobuf2-core.h                | 20 +++++++++--
 samples/v4l/v4l2-pci-skeleton.c               |  2 +-
 68 files changed, 121 insertions(+), 99 deletions(-)

Comments

Hans Verkuil Dec. 13, 2023, 4:39 p.m. UTC | #1
Hi Benjamin,

On 11/12/2023 14:32, Benjamin Gaignard wrote:
> Rename min_buffers_needed into min_queued_buffers and update
> the documentation about it.

I merged this patch, but not the others. I also dropped one functional
change:

<snip>

> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
> index 40d89f29fa33..8912dff5bde3 100644
> --- a/drivers/media/common/videobuf2/videobuf2-core.c
> +++ b/drivers/media/common/videobuf2/videobuf2-core.c
> @@ -865,7 +865,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>  	/*
>  	 * Make sure the requested values and current defaults are sane.
>  	 */
> -	num_buffers = max_t(unsigned int, *count, q->min_buffers_needed);
> +	num_buffers = max_t(unsigned int, *count, q->min_queued_buffers + 1);
>  	num_buffers = min_t(unsigned int, num_buffers, q->max_num_buffers);
>  	memset(q->alloc_devs, 0, sizeof(q->alloc_devs));
>  	/*

That "+ 1" didn't really belong here, since everything else was just renaming a
field. Such a patch shouldn't make any other changes.

There were also three more occurrences of min_buffers_needed (one in a comment,
two in a vivid function argument), and I renamed those as well.

'git grep min_buffers_needed' now no longer shows any hits.

I decided not to take the other patches, I think it is best if you rebase
and repost the series on top of staging and in the new year we'll continue with
it. I did not feel that I had enough time to really review the remaining patches.

However, it is nice to have this large rename patch merged. It touches on a lot
of files, so it is annoying to have to carry that around. And now was a good
moment to merge it.

Regards,

	Hans
Benjamin Gaignard Dec. 14, 2023, 3:41 p.m. UTC | #2
Le 13/12/2023 à 17:39, Hans Verkuil a écrit :
> Hi Benjamin,
>
> On 11/12/2023 14:32, Benjamin Gaignard wrote:
>> Rename min_buffers_needed into min_queued_buffers and update
>> the documentation about it.
> I merged this patch, but not the others. I also dropped one functional
> change:
>
> <snip>
>
>> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
>> index 40d89f29fa33..8912dff5bde3 100644
>> --- a/drivers/media/common/videobuf2/videobuf2-core.c
>> +++ b/drivers/media/common/videobuf2/videobuf2-core.c
>> @@ -865,7 +865,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>>   	/*
>>   	 * Make sure the requested values and current defaults are sane.
>>   	 */
>> -	num_buffers = max_t(unsigned int, *count, q->min_buffers_needed);
>> +	num_buffers = max_t(unsigned int, *count, q->min_queued_buffers + 1);
>>   	num_buffers = min_t(unsigned int, num_buffers, q->max_num_buffers);
>>   	memset(q->alloc_devs, 0, sizeof(q->alloc_devs));
>>   	/*
> That "+ 1" didn't really belong here, since everything else was just renaming a
> field. Such a patch shouldn't make any other changes.
>
> There were also three more occurrences of min_buffers_needed (one in a comment,
> two in a vivid function argument), and I renamed those as well.
>
> 'git grep min_buffers_needed' now no longer shows any hits.
>
> I decided not to take the other patches, I think it is best if you rebase
> and repost the series on top of staging and in the new year we'll continue with
> it. I did not feel that I had enough time to really review the remaining patches.

Do you want me to re-post only the two missing patches or should I add the patches for
delete buffers feature since it is the ultimate goal of this ?

Regards,
Benjamin

>
> However, it is nice to have this large rename patch merged. It touches on a lot
> of files, so it is annoying to have to carry that around. And now was a good
> moment to merge it.
>
> Regards,
>
> 	Hans
>
Tomasz Figa Dec. 26, 2023, 8:23 a.m. UTC | #3
Hi Benjamin,

On Mon, Dec 11, 2023 at 02:32:49PM +0100, Benjamin Gaignard wrote:
> Rename min_buffers_needed into min_queued_buffers and update
> the documentation about it.
> 

Sorry for being late to the party. I think this is generally a good idea,
thanks for doing this! Just one comment inline.

[snip]
> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
> index 40d89f29fa33..8912dff5bde3 100644
> --- a/drivers/media/common/videobuf2/videobuf2-core.c
> +++ b/drivers/media/common/videobuf2/videobuf2-core.c
> @@ -865,7 +865,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>  	/*
>  	 * Make sure the requested values and current defaults are sane.
>  	 */
> -	num_buffers = max_t(unsigned int, *count, q->min_buffers_needed);
> +	num_buffers = max_t(unsigned int, *count, q->min_queued_buffers + 1);

Where does this + 1 come from here?
Agreed with Hans that this change deserves its own patch with a proper
explanation in its description.

>  	num_buffers = min_t(unsigned int, num_buffers, q->max_num_buffers);
>  	memset(q->alloc_devs, 0, sizeof(q->alloc_devs));
>  	/*
> @@ -917,7 +917,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>  	 * There is no point in continuing if we can't allocate the minimum
>  	 * number of buffers needed by this vb2_queue.
>  	 */
> -	if (allocated_buffers < q->min_buffers_needed)
> +	if (allocated_buffers < q->min_queued_buffers)
>  		ret = -ENOMEM;
>  
>  	/*
> @@ -1653,7 +1653,7 @@ EXPORT_SYMBOL_GPL(vb2_core_prepare_buf);
>   * @q:		videobuf2 queue
>   *
>   * Attempt to start streaming. When this function is called there must be
> - * at least q->min_buffers_needed buffers queued up (i.e. the minimum
> + * at least q->min_queued_buffers queued up (i.e. the minimum
>   * number of buffers required for the DMA engine to function). If the
>   * @start_streaming op fails it is supposed to return all the driver-owned
>   * buffers back to vb2 in state QUEUED. Check if that happened and if
> @@ -1846,7 +1846,7 @@ int vb2_core_qbuf(struct vb2_queue *q, struct vb2_buffer *vb, void *pb,
>  	 * then we can finally call start_streaming().
>  	 */
>  	if (q->streaming && !q->start_streaming_called &&
> -	    q->queued_count >= q->min_buffers_needed) {
> +	    q->queued_count >= q->min_queued_buffers) {
>  		ret = vb2_start_streaming(q);
>  		if (ret) {
>  			/*
> @@ -2210,9 +2210,9 @@ int vb2_core_streamon(struct vb2_queue *q, unsigned int type)
>  		return -EINVAL;
>  	}
>  
> -	if (q_num_bufs < q->min_buffers_needed) {
> -		dprintk(q, 1, "need at least %u allocated buffers\n",
> -				q->min_buffers_needed);
> +	if (q_num_bufs < q->min_queued_buffers) {
> +		dprintk(q, 1, "need at least %u queued buffers\n",

Note that the value being checked here is the number of allocated buffers,
not queued buffers. So basically we're enforcing here that at the time
STREAMON is called, there is enough buffers allocated to queue the minimum
number of buffers to start streaming, but then later down we're not
actually enforcing that they are queued - if not, the queue start_streaming
operation is deferred until enough buffers are queued.

The question is: Do we really want this to be an error? Or should we just
be consistent with the allocated-but-not-queued case and let the
application allocate more buffers later using CREATE_BUFS?
(Another question: How does an application know how many buffers to
allocate for STREAMON to work?)

That said, this doesn't really affect the correctness of the patch itself.
Just some additional oddity in the current implementation that we could
simplify in the future.

> +			q->min_queued_buffers);
>  		return -EINVAL;
>  	}
>  
[snip]
> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
> index 5557d78b6f20..f9a00b6c3c46 100644
> --- a/include/media/videobuf2-core.h
> +++ b/include/media/videobuf2-core.h
> @@ -546,10 +546,13 @@ struct vb2_buf_ops {
>   * @gfp_flags:	additional gfp flags used when allocating the buffers.
>   *		Typically this is 0, but it may be e.g. %GFP_DMA or %__GFP_DMA32
>   *		to force the buffer allocation to a specific memory zone.
> - * @min_buffers_needed: the minimum number of buffers needed before
> + * @min_queued_buffers: the minimum number of queued buffers needed before
>   *		@start_streaming can be called. Used when a DMA engine
>   *		cannot be started unless at least this number of buffers
>   *		have been queued into the driver.
> + *		VIDIOC_REQBUFS will ensure at least @min_queued_buffers + 1
> + *		buffers will be allocated. Note that VIDIOC_CREATE_BUFS will not
> + *		modify the requested buffer count.

Same here, this + 1 needs a proper explanation.
Also, I don't like this API inconsistency where REQBUFS guarantees the
right number of buffers, but CREATE_BUFS doesn't. In fact, would an
application have a way to know how many buffers to allocate if it simply
wants to use CREATE_BUFS?

(It's generally related to the oddity that I pointed out above. Maybe we
should let the allocation code only handle allocation constraints and not
care about STREAMON constraints?)

[snip]

Best regards,
Tomasz
Benjamin Gaignard Jan. 3, 2024, 8:38 a.m. UTC | #4
Le 26/12/2023 à 09:23, Tomasz Figa a écrit :
> Hi Benjamin,
>
> On Mon, Dec 11, 2023 at 02:32:49PM +0100, Benjamin Gaignard wrote:
>> Rename min_buffers_needed into min_queued_buffers and update
>> the documentation about it.
>>
> Sorry for being late to the party. I think this is generally a good idea,
> thanks for doing this! Just one comment inline.
>
> [snip]
>> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
>> index 40d89f29fa33..8912dff5bde3 100644
>> --- a/drivers/media/common/videobuf2/videobuf2-core.c
>> +++ b/drivers/media/common/videobuf2/videobuf2-core.c
>> @@ -865,7 +865,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>>   	/*
>>   	 * Make sure the requested values and current defaults are sane.
>>   	 */
>> -	num_buffers = max_t(unsigned int, *count, q->min_buffers_needed);
>> +	num_buffers = max_t(unsigned int, *count, q->min_queued_buffers + 1);
> Where does this + 1 come from here?
> Agreed with Hans that this change deserves its own patch with a proper
> explanation in its description.

Hans have merged this patch without this line.
Since I still aiming to add delete buffers feature I have include this change
in this series:
https://www.spinics.net/lists/linux-media/msg246289.html

Regards,
Benjamin

>
>>   	num_buffers = min_t(unsigned int, num_buffers, q->max_num_buffers);
>>   	memset(q->alloc_devs, 0, sizeof(q->alloc_devs));
>>   	/*
>> @@ -917,7 +917,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>>   	 * There is no point in continuing if we can't allocate the minimum
>>   	 * number of buffers needed by this vb2_queue.
>>   	 */
>> -	if (allocated_buffers < q->min_buffers_needed)
>> +	if (allocated_buffers < q->min_queued_buffers)
>>   		ret = -ENOMEM;
>>   
>>   	/*
>> @@ -1653,7 +1653,7 @@ EXPORT_SYMBOL_GPL(vb2_core_prepare_buf);
>>    * @q:		videobuf2 queue
>>    *
>>    * Attempt to start streaming. When this function is called there must be
>> - * at least q->min_buffers_needed buffers queued up (i.e. the minimum
>> + * at least q->min_queued_buffers queued up (i.e. the minimum
>>    * number of buffers required for the DMA engine to function). If the
>>    * @start_streaming op fails it is supposed to return all the driver-owned
>>    * buffers back to vb2 in state QUEUED. Check if that happened and if
>> @@ -1846,7 +1846,7 @@ int vb2_core_qbuf(struct vb2_queue *q, struct vb2_buffer *vb, void *pb,
>>   	 * then we can finally call start_streaming().
>>   	 */
>>   	if (q->streaming && !q->start_streaming_called &&
>> -	    q->queued_count >= q->min_buffers_needed) {
>> +	    q->queued_count >= q->min_queued_buffers) {
>>   		ret = vb2_start_streaming(q);
>>   		if (ret) {
>>   			/*
>> @@ -2210,9 +2210,9 @@ int vb2_core_streamon(struct vb2_queue *q, unsigned int type)
>>   		return -EINVAL;
>>   	}
>>   
>> -	if (q_num_bufs < q->min_buffers_needed) {
>> -		dprintk(q, 1, "need at least %u allocated buffers\n",
>> -				q->min_buffers_needed);
>> +	if (q_num_bufs < q->min_queued_buffers) {
>> +		dprintk(q, 1, "need at least %u queued buffers\n",
> Note that the value being checked here is the number of allocated buffers,
> not queued buffers. So basically we're enforcing here that at the time
> STREAMON is called, there is enough buffers allocated to queue the minimum
> number of buffers to start streaming, but then later down we're not
> actually enforcing that they are queued - if not, the queue start_streaming
> operation is deferred until enough buffers are queued.
>
> The question is: Do we really want this to be an error? Or should we just
> be consistent with the allocated-but-not-queued case and let the
> application allocate more buffers later using CREATE_BUFS?
> (Another question: How does an application know how many buffers to
> allocate for STREAMON to work?)
>
> That said, this doesn't really affect the correctness of the patch itself.
> Just some additional oddity in the current implementation that we could
> simplify in the future.
>
>> +			q->min_queued_buffers);
>>   		return -EINVAL;
>>   	}
>>   
> [snip]
>> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
>> index 5557d78b6f20..f9a00b6c3c46 100644
>> --- a/include/media/videobuf2-core.h
>> +++ b/include/media/videobuf2-core.h
>> @@ -546,10 +546,13 @@ struct vb2_buf_ops {
>>    * @gfp_flags:	additional gfp flags used when allocating the buffers.
>>    *		Typically this is 0, but it may be e.g. %GFP_DMA or %__GFP_DMA32
>>    *		to force the buffer allocation to a specific memory zone.
>> - * @min_buffers_needed: the minimum number of buffers needed before
>> + * @min_queued_buffers: the minimum number of queued buffers needed before
>>    *		@start_streaming can be called. Used when a DMA engine
>>    *		cannot be started unless at least this number of buffers
>>    *		have been queued into the driver.
>> + *		VIDIOC_REQBUFS will ensure at least @min_queued_buffers + 1
>> + *		buffers will be allocated. Note that VIDIOC_CREATE_BUFS will not
>> + *		modify the requested buffer count.
> Same here, this + 1 needs a proper explanation.
> Also, I don't like this API inconsistency where REQBUFS guarantees the
> right number of buffers, but CREATE_BUFS doesn't. In fact, would an
> application have a way to know how many buffers to allocate if it simply
> wants to use CREATE_BUFS?
>
> (It's generally related to the oddity that I pointed out above. Maybe we
> should let the allocation code only handle allocation constraints and not
> care about STREAMON constraints?)
>
> [snip]
>
> Best regards,
> Tomasz