Re: [PATCH for v5.2] videobuf2-core.c: always reacquire USERPTR memory

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Hans,

Thank you for the patch.

On Fri, Jun 07, 2019 at 10:45:31AM +0200, Hans Verkuil wrote:
> The __prepare_userptr() function made the incorrect assumption that if the
> same user pointer was used as the last one for which memory was acquired, then
> there was no need to re-acquire the memory. This assumption was never properly
> tested, and after doing that it became clear that this was in fact wrong.

Could you explain in the commit message why the assumption is not
correct ?

> Change the behavior to always reacquire memory.

One more reason to not use USERPTR :-)

> Signed-off-by: Hans Verkuil <hverkuil-cisco@xxxxxxxxx>
> Reported-by: Tomasz Figa <tfiga@xxxxxxxxxxxx>
> Cc: <stable@xxxxxxxxxxxxxxx>      # for v5.1 and up
> ---
> This should be backported to all stable kernels, unfortunately this patch only
> applies cleanly to 5.1, so this has to be backported manually.
> ---
> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
> index 4489744fbbd9..a6400391117f 100644
> --- a/drivers/media/common/videobuf2/videobuf2-core.c
> +++ b/drivers/media/common/videobuf2/videobuf2-core.c
> @@ -1013,7 +1013,7 @@ static int __prepare_userptr(struct vb2_buffer *vb)
>  	void *mem_priv;
>  	unsigned int plane;
>  	int ret = 0;
> -	bool reacquired = vb->planes[0].mem_priv == NULL;
> +	bool called_cleanup = false;
> 
>  	memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
>  	/* Copy relevant information provided by the userspace */
> @@ -1023,15 +1023,6 @@ static int __prepare_userptr(struct vb2_buffer *vb)
>  		return ret;
> 
>  	for (plane = 0; plane < vb->num_planes; ++plane) {
> -		/* Skip the plane if already verified */
> -		if (vb->planes[plane].m.userptr &&
> -			vb->planes[plane].m.userptr == planes[plane].m.userptr
> -			&& vb->planes[plane].length == planes[plane].length)
> -			continue;
> -
> -		dprintk(3, "userspace address for plane %d changed, reacquiring memory\n",
> -			plane);
> -
>  		/* Check if the provided plane buffer is large enough */
>  		if (planes[plane].length < vb->planes[plane].min_length) {
>  			dprintk(1, "provided buffer size %u is less than setup size %u for plane %d\n",
> @@ -1044,8 +1035,8 @@ static int __prepare_userptr(struct vb2_buffer *vb)
> 
>  		/* Release previously acquired memory if present */
>  		if (vb->planes[plane].mem_priv) {
> -			if (!reacquired) {
> -				reacquired = true;
> +			if (!called_cleanup) {
> +				called_cleanup = true;
>  				vb->copied_timestamp = 0;
>  				call_void_vb_qop(vb, buf_cleanup, vb);
>  			}

Could we do this unconditionally before the loop ?

> @@ -1083,17 +1074,14 @@ static int __prepare_userptr(struct vb2_buffer *vb)
>  		vb->planes[plane].data_offset = planes[plane].data_offset;
>  	}
> 
> -	if (reacquired) {
> -		/*
> -		 * One or more planes changed, so we must call buf_init to do
> -		 * the driver-specific initialization on the newly acquired
> -		 * buffer, if provided.
> -		 */
> -		ret = call_vb_qop(vb, buf_init, vb);
> -		if (ret) {
> -			dprintk(1, "buffer initialization failed\n");
> -			goto err;
> -		}
> +	/*
> +	 * Call buf_init to do the driver-specific initialization on
> +	 * the newly acquired buffer.
> +	 */
> +	ret = call_vb_qop(vb, buf_init, vb);
> +	if (ret) {
> +		dprintk(1, "buffer initialization failed\n");
> +		goto err;
>  	}
> 
>  	ret = call_vb_qop(vb, buf_prepare, vb);

-- 
Regards,

Laurent Pinchart



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux