public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Hans Verkuil <hverkuil@xs4all.nl>
Cc: linux-media@vger.kernel.org, m.szyprowski@samsung.com,
	pawel@osciak.com, awalls@md.metrocast.net,
	Hans Verkuil <hans.verkuil@cisco.com>
Subject: Re: [RFCv2 PATCH 1/9] vb2: push the mmap semaphore down to __buf_prepare()
Date: Wed, 04 Dec 2013 02:15:52 +0100	[thread overview]
Message-ID: <2001434.ZTVRbYTb7A@avalon> (raw)
In-Reply-To: <529DA74E.6080902@xs4all.nl>

Hi Hans,

On Tuesday 03 December 2013 10:41:34 Hans Verkuil wrote:
> On 11/29/13 19:16, Laurent Pinchart wrote:
> > On Friday 29 November 2013 10:58:36 Hans Verkuil wrote:
> >> From: Hans Verkuil <hans.verkuil@cisco.com>
> >> 
> >> Rather than taking the mmap semaphore at a relatively high-level
> >> function, push it down to the place where it is really needed.
> >> 
> >> It was placed in vb2_queue_or_prepare_buf() to prevent racing with other
> >> vb2 calls. The only way I can see that a race can happen is when two
> >> threads queue the same buffer. The solution for that it to introduce
> >> a PREPARING state.
> > 
> > This looks better to me, but what about a vb2_reqbufs(0) call being
> > processed during the time window where we release the queue mutex ?
> 
> You have a nasty mind.

I wonder how I should take that :-)

> That can still go wrong, but note that this is true for the existing code as
> well as far as I can tell.

Yes, that's right.

> How about this patch to fix this race?
> 
> It just refuses to free buffers if any of them is in the preparing state.
> It returns EAGAIN in that case (or would EBUSY be better?).

I would have argued that applications might not be prepared to handle such an 
error when calling REQBUFS(0), but they shouldn't trigger that in the first 
place anyway. The patch looks good to me.

> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> 
> diff --git a/drivers/media/v4l2-core/videobuf2-core.c
> b/drivers/media/v4l2-core/videobuf2-core.c index 2aff646..c3ff993 100644
> --- a/drivers/media/v4l2-core/videobuf2-core.c
> +++ b/drivers/media/v4l2-core/videobuf2-core.c
> @@ -284,10 +284,28 @@ static void __vb2_free_mem(struct vb2_queue *q,
> unsigned int buffers) * 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 int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
>  {
>  	unsigned int buffer;
> 
> +	/*
> +	 * Sanity check: when preparing a buffer the queue lock is released for
> +	 * a short while (see __buf_prepare for the details), which would allow
> +	 * a race with a reqbufs which can call this function. Removing the
> +	 * buffers from underneath __buf_prepare is obviously a bad idea, so we
> +	 * check if any of the buffers is in the state PREPARING, and if so we
> +	 * just return -EAGAIN.
> +	 */
> +	for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
> +	     ++buffer) {
> +		if (q->bufs[buffer] == NULL)
> +			continue;
> +		if (q->bufs[buffer]->state == VB2_BUF_STATE_PREPARING) {
> +			dprintk(1, "reqbufs: preparing buffers, cannot free\n");
> +			return -EAGAIN;
> +		}
> +	}
> +
>  	/* Call driver-provided cleanup function for each buffer, if provided */
>  	if (q->ops->buf_cleanup) {
>  		for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
> @@ -312,6 +330,7 @@ static void __vb2_queue_free(struct vb2_queue *q,
> unsigned int buffers) if (!q->num_buffers)
>  		q->memory = 0;
>  	INIT_LIST_HEAD(&q->queued_list);
> +	return 0;
>  }
> 
>  /**
> @@ -644,7 +663,9 @@ static int __reqbufs(struct vb2_queue *q, struct
> v4l2_requestbuffers *req) return -EBUSY;
>  		}
> 
> -		__vb2_queue_free(q, q->num_buffers);
> +		ret = __vb2_queue_free(q, q->num_buffers);
> +		if (ret)
> +			return ret;
> 
>  		/*
>  		 * In case of REQBUFS(0) return immediately without calling
-- 
Regards,

Laurent Pinchart


  reply	other threads:[~2013-12-04  1:15 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-29  9:58 [RFCv2 PATCH 0/9] vb2: various cleanups and improvements Hans Verkuil
2013-11-29  9:58 ` [RFCv2 PATCH 1/9] vb2: push the mmap semaphore down to __buf_prepare() Hans Verkuil
2013-11-29  9:58   ` [RFCv2 PATCH 2/9] vb2: simplify qbuf/prepare_buf by removing callback Hans Verkuil
2013-11-29  9:58   ` [RFCv2 PATCH 3/9] vb2: remove the 'fileio = NULL' hack Hans Verkuil
2013-11-29  9:58   ` [RFCv2 PATCH 4/9] vb2: retry start_streaming in case of insufficient buffers Hans Verkuil
2013-12-04 13:42     ` Marek Szyprowski
2013-11-29  9:58   ` [RFCv2 PATCH 5/9] vb2: don't set index, don't start streaming for write() Hans Verkuil
2013-11-29  9:58   ` [RFCv2 PATCH 6/9] vb2: return ENODATA in start_streaming in case of too few buffers Hans Verkuil
2013-11-29  9:58   ` [RFCv2 PATCH 7/9] vb2: add thread support Hans Verkuil
2013-11-29 18:21     ` Laurent Pinchart
2013-12-03  9:56       ` Hans Verkuil
2013-12-04  1:17         ` Laurent Pinchart
2013-12-04  7:47           ` Hans Verkuil
2013-12-04 16:33             ` Laurent Pinchart
2013-12-04 17:03               ` Hans Verkuil
2013-12-04 20:57                 ` Laurent Pinchart
2013-11-29  9:58   ` [RFCv2 PATCH 8/9] vb2: Add videobuf2-dvb support Hans Verkuil
2013-11-29  9:58   ` [RFCv2 PATCH 9/9] vb2: Improve file I/O emulation to handle buffers in any order Hans Verkuil
2013-11-29 18:16   ` [RFCv2 PATCH 1/9] vb2: push the mmap semaphore down to __buf_prepare() Laurent Pinchart
2013-12-03  9:41     ` Hans Verkuil
2013-12-04  1:15       ` Laurent Pinchart [this message]
2013-11-29 10:17 ` [RFCv2 PATCH 0/9] vb2: various cleanups and improvements Hans Verkuil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2001434.ZTVRbYTb7A@avalon \
    --to=laurent.pinchart@ideasonboard.com \
    --cc=awalls@md.metrocast.net \
    --cc=hans.verkuil@cisco.com \
    --cc=hverkuil@xs4all.nl \
    --cc=linux-media@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=pawel@osciak.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox