linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Hans de Goede <hdegoede@redhat.com>
To: Antonio Ospite <ao2@ao2.it>, Linux Media <linux-media@vger.kernel.org>
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Subject: Re: [PATCH 7/7] [media] gspca: fix a v4l2-compliance failure during read()
Date: Thu, 10 Mar 2016 16:59:45 +0100	[thread overview]
Message-ID: <56E199F1.5070707@redhat.com> (raw)
In-Reply-To: <1457539401-11515-8-git-send-email-ao2@ao2.it>

Hi,

On 09-03-16 17:03, Antonio Ospite wrote:
> v4l2-compliance fails with this message:
>
>    fail: v4l2-test-buffers.cpp(512): Expected EBUSY, got 22
>    test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: FAIL
>
> Looking at the v4l2-compliance code reveals that this failure is about
> the read() callback.
>
> In gspca, dev_read() is calling vidioc_dqbuf() which calls
> frame_ready_nolock() but the latter returns -EINVAL in a case when
> v4l2-compliance expects -EBUSY.
>
> Fix the failure by changing the return value in frame_ready_nolock().
>
> Signed-off-by: Antonio Ospite <ao2@ao2.it>
> ---
>   drivers/media/usb/gspca/gspca.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
> index 915b6c7..de7e300 100644
> --- a/drivers/media/usb/gspca/gspca.c
> +++ b/drivers/media/usb/gspca/gspca.c
> @@ -1664,7 +1664,7 @@ static int frame_ready_nolock(struct gspca_dev *gspca_dev, struct file *file,
>   		return -ENODEV;
>   	if (gspca_dev->capt_file != file || gspca_dev->memory != memory ||
>   			!gspca_dev->streaming)
> -		return -EINVAL;
> +		return -EBUSY;
>
>   	/* check if a frame is ready */
>   	return gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i);

I'm not sure that this is the right fix:


1) !gspca_dev->streaming should result in -EINVAL, this is the same as what videobuf2 is doing
2) gspca_dev->memory != memory should result in -EINVAL
3) gspca_dev->capt_file != file means calling dqbuf without having done reqbufs (through the same fd)
    which certainly seemes like -EINVAL to me.

The actual problem is that dev_read() is not catching that mmap is being in use:

static ssize_t dev_read(struct file *file, char __user *data,
                     size_t count, loff_t *ppos)
{
...
         if (gspca_dev->memory == GSPCA_MEMORY_NO) { /* first time ? */
                 ret = read_alloc(gspca_dev, file);
                 if (ret != 0)
                         return ret;
         }

It will skip the read_alloc since gspca_dev->memory is USERPTR or MMAP
and then do a dqbuf with memory == GSPCA_MEMORY_READ, triggering the
gspca_dev->memory != memory check.

There are a couple of issues here:

1) gspca_dev->memory check without holding usb_lock, the taking and
releasing of usb_lock should be moved from read_alloc() into dev_read()
itself.

2) dev_read() should not assume that reading is ok if
    gspca_dev->memory == GSPCA_MEMORY_NO, it needs a:

if (gspca_dev->memory != GSPCA_MEMORY_NO &&
     gspca_dev->memory != GSPCA_MEMORY_READ)
     return -EBUSY;

(while holding the usb_lock so the above is wrong)

3) If gspca_dev->memory == GSPCA_MEMORY_READ already the
    stream could have been stopped. so we need to check
    gspca_dev->streaming (while holding the usb_lock)
    and do a streamon if it is not set (and then we can
    remove the streamon from read_alloc())

So TL;DR: dev_read needs some love.

Regards,

Hans


p.s.

If you've time to work on v4l2 stuff what gspca really needs
is to just have its buffer handling ripped out and be rewritten
to use videobuf2. I would certainly love to see a patch for that.


  reply	other threads:[~2016-03-10 15:59 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-09 16:03 [PATCH 0/7] gspca: pass all v4l2-compliance tests + minor fixes Antonio Ospite
2016-03-09 16:03 ` [PATCH 1/7] [media] gspca: ov534/topro: use a define for the default framerate Antonio Ospite
2016-03-09 16:03 ` [PATCH 2/7] [media] gspca: fix setting frame interval type in vidioc_enum_frameintervals() Antonio Ospite
2016-03-09 16:03 ` [PATCH 3/7] [media] gspca: rename wxh_to_mode() to wxh_to_nearest_mode() Antonio Ospite
2016-03-09 16:03 ` [PATCH 4/7] [media] gspca: fix a v4l2-compliance failure about VIDIOC_ENUM_FRAMEINTERVALS Antonio Ospite
2016-03-09 16:03 ` [PATCH 5/7] [media] gspca: fix a v4l2-compliance failure about buffer timestamp Antonio Ospite
2016-03-09 16:03 ` [PATCH 6/7] [media] gspca: fix a v4l2-compliance failure during VIDIOC_REQBUFS Antonio Ospite
2016-03-09 16:10   ` Hans Verkuil
2016-03-10 14:54   ` Hans de Goede
2016-03-14 15:02     ` Antonio Ospite
2016-03-14 15:34       ` Hans de Goede
2016-03-09 16:03 ` [PATCH 7/7] [media] gspca: fix a v4l2-compliance failure during read() Antonio Ospite
2016-03-10 15:59   ` Hans de Goede [this message]
2016-03-14 15:11     ` Antonio Ospite

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=56E199F1.5070707@redhat.com \
    --to=hdegoede@redhat.com \
    --cc=ao2@ao2.it \
    --cc=hverkuil@xs4all.nl \
    --cc=linux-media@vger.kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).