Re: [PATCH 7/7] [media] gspca: fix a v4l2-compliance failure during read()

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

 



On Thu, 10 Mar 2016 16:59:45 +0100
Hans de Goede <hdegoede@xxxxxxxxxx> wrote:

> 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@xxxxxx>
> > ---
> >   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.
>

I'll try to take a look at this too later this week.

> 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.
> 

It'd be an interesting tasklet but I don't know when I'll be able to do
that.

Ciao,
   Antonio

-- 
Antonio Ospite
http://ao2.it

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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