Re: uvcvideo kernel panic when using libv4l

2009-12-16 Thread leandro Costantino
That sould be the correct.
Pablo, note that using svv.c with read method as implemented there,
should work ok.
http://moinejf.free.fr/svv.c


On Wed, Dec 16, 2009 at 7:51 AM, Pablo Baena pba...@gmail.com wrote:
 With that patch, libv4l throws an error at some point, no crashes so far 
 though:

 libv4l2: error dequeuing buf: Invalid argument
 read error 22, Invalid argument

 On Tue, Dec 15, 2009 at 9:12 PM, Laurent Pinchart
 laurent.pinch...@ideasonboard.com wrote:
 Hi Leandro and Pablo,

 could you please try the following patch ? It closes a race window that I
 believe could be at the core of your kernel panic.

 diff -r c1f376eae978 linux/drivers/media/video/uvc/uvc_queue.c
 --- a/linux/drivers/media/video/uvc/uvc_queue.c Sat Dec 12 18:57:17 2009 
 +0100
 +++ b/linux/drivers/media/video/uvc/uvc_queue.c Wed Dec 16 01:10:21 2009 
 +0100
 @@ -59,7 +59,7 @@
  *    returns immediately.
  *
  *    When the buffer is full, the completion handler removes it from the irq
 - *    queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait 
 queue.
 + *    queue, marks it as ready (UVC_BUF_STATE_READY) and wakes its wait 
 queue.
  *    At that point, any process waiting on the buffer will be woken up. If a
  *    process tries to dequeue a buffer after it has been marked ready, the
  *    dequeing will succeed immediately.
 @@ -196,11 +196,12 @@

        switch (buf-state) {
        case UVC_BUF_STATE_ERROR:
 -       case UVC_BUF_STATE_DONE:
 +       case UVC_BUF_STATE_READY:
                v4l2_buf-flags |= V4L2_BUF_FLAG_DONE;
                break;
        case UVC_BUF_STATE_QUEUED:
        case UVC_BUF_STATE_ACTIVE:
 +       case UVC_BUF_STATE_DONE:
                v4l2_buf-flags |= V4L2_BUF_FLAG_QUEUED;
                break;
        case UVC_BUF_STATE_IDLE:
 @@ -341,13 +342,14 @@
                uvc_trace(UVC_TRACE_CAPTURE, [W] Corrupted data 
                        (transmission error).\n);
                ret = -EIO;
 -       case UVC_BUF_STATE_DONE:
 +       case UVC_BUF_STATE_READY:
                buf-state = UVC_BUF_STATE_IDLE;
                break;

        case UVC_BUF_STATE_IDLE:
        case UVC_BUF_STATE_QUEUED:
        case UVC_BUF_STATE_ACTIVE:
 +       case UVC_BUF_STATE_DONE:
        default:
                uvc_trace(UVC_TRACE_CAPTURE, [E] Invalid buffer state %u 
                        (driver bug?).\n, buf-state);
 @@ -383,7 +385,7 @@
        buf = list_first_entry(queue-mainqueue, struct uvc_buffer, stream);

        poll_wait(file, buf-wait, wait);
 -       if (buf-state == UVC_BUF_STATE_DONE ||
 +       if (buf-state == UVC_BUF_STATE_READY ||
            buf-state == UVC_BUF_STATE_ERROR)
                mask |= POLLIN | POLLRDNORM;

 @@ -489,6 +491,7 @@

        spin_lock_irqsave(queue-irqlock, flags);
        list_del(buf-queue);
 +       buf-state = UVC_BUF_STATE_READY;
        if (!list_empty(queue-irqqueue))
                nextbuf = list_first_entry(queue-irqqueue, struct 
 uvc_buffer,
                                           queue);
 diff -r c1f376eae978 linux/drivers/media/video/uvc/uvc_video.c
 --- a/linux/drivers/media/video/uvc/uvc_video.c Sat Dec 12 18:57:17 2009 
 +0100
 +++ b/linux/drivers/media/video/uvc/uvc_video.c Wed Dec 16 01:10:21 2009 
 +0100
 @@ -578,8 +578,7 @@
                uvc_video_decode_end(stream, buf, mem,
                        urb-iso_frame_desc[i].actual_length);

 -               if (buf-state == UVC_BUF_STATE_DONE ||
 -                   buf-state == UVC_BUF_STATE_ERROR)
 +               if (buf-state == UVC_BUF_STATE_DONE)
                        buf = uvc_queue_next_buffer(stream-queue, buf);
        }
  }
 @@ -637,8 +636,7 @@
                if (!stream-bulk.skip_payload  buf != NULL) {
                        uvc_video_decode_end(stream, buf, stream-bulk.header,
                                stream-bulk.payload_size);
 -                       if (buf-state == UVC_BUF_STATE_DONE ||
 -                           buf-state == UVC_BUF_STATE_ERROR)
 +                       if (buf-state == UVC_BUF_STATE_DONE)
                                buf = uvc_queue_next_buffer(stream-queue,
                                                            buf);
                }
 diff -r c1f376eae978 linux/drivers/media/video/uvc/uvcvideo.h
 --- a/linux/drivers/media/video/uvc/uvcvideo.h  Sat Dec 12 18:57:17 2009 
 +0100
 +++ b/linux/drivers/media/video/uvc/uvcvideo.h  Wed Dec 16 01:10:21 2009 
 +0100
 @@ -370,7 +370,8 @@
        UVC_BUF_STATE_QUEUED    = 1,
        UVC_BUF_STATE_ACTIVE    = 2,
        UVC_BUF_STATE_DONE      = 3,
 -       UVC_BUF_STATE_ERROR     = 4,
 +       UVC_BUF_STATE_READY     = 4,
 +       UVC_BUF_STATE_ERROR     = 5,
  };

  struct uvc_buffer {

 --
 Regards,

 Laurent Pinchart




 --
 Not possessing the gift of reflection, a dog does not know that he
 does not know, and does not understand that he understands nothing;
 we, on the other hand, are aware of both. If we behave otherwise, it
 is from stupidity, or else from 

Re: uvcvideo kernel panic when using libv4l

2009-12-16 Thread Laurent Pinchart
Hi Pablo,

On Wednesday 16 December 2009 07:51:20 Pablo Baena wrote:
 With that patch, libv4l throws an error at some point, no crashes so far
  though:
 
 libv4l2: error dequeuing buf: Invalid argument
 read error 22, Invalid argument

Could you please try this updated patch ?

diff -r c1f376eae978 linux/drivers/media/video/uvc/uvc_queue.c
--- a/linux/drivers/media/video/uvc/uvc_queue.c Sat Dec 12 18:57:17 2009 +0100
+++ b/linux/drivers/media/video/uvc/uvc_queue.c Wed Dec 16 11:47:40 2009 +0100
@@ -59,7 +59,7 @@
  *returns immediately.
  *
  *When the buffer is full, the completion handler removes it from the irq
- *queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue.
+ *queue, marks it as ready (UVC_BUF_STATE_READY) and wakes its wait queue.
  *At that point, any process waiting on the buffer will be woken up. If a
  *process tries to dequeue a buffer after it has been marked ready, the
  *dequeing will succeed immediately.
@@ -196,11 +196,12 @@
 
switch (buf-state) {
case UVC_BUF_STATE_ERROR:
-   case UVC_BUF_STATE_DONE:
+   case UVC_BUF_STATE_READY:
v4l2_buf-flags |= V4L2_BUF_FLAG_DONE;
break;
case UVC_BUF_STATE_QUEUED:
case UVC_BUF_STATE_ACTIVE:
+   case UVC_BUF_STATE_DONE:
v4l2_buf-flags |= V4L2_BUF_FLAG_QUEUED;
break;
case UVC_BUF_STATE_IDLE:
@@ -295,13 +296,15 @@
 {
if (nonblocking) {
return (buf-state != UVC_BUF_STATE_QUEUED 
-   buf-state != UVC_BUF_STATE_ACTIVE)
+   buf-state != UVC_BUF_STATE_ACTIVE 
+   buf-state != UVC_BUF_STATE_DONE)
? 0 : -EAGAIN;
}
 
return wait_event_interruptible(buf-wait,
buf-state != UVC_BUF_STATE_QUEUED 
-   buf-state != UVC_BUF_STATE_ACTIVE);
+   buf-state != UVC_BUF_STATE_ACTIVE 
+   buf-state != UVC_BUF_STATE_DONE);
 }
 
 /*
@@ -341,13 +344,14 @@
uvc_trace(UVC_TRACE_CAPTURE, [W] Corrupted data 
(transmission error).\n);
ret = -EIO;
-   case UVC_BUF_STATE_DONE:
+   case UVC_BUF_STATE_READY:
buf-state = UVC_BUF_STATE_IDLE;
break;
 
case UVC_BUF_STATE_IDLE:
case UVC_BUF_STATE_QUEUED:
case UVC_BUF_STATE_ACTIVE:
+   case UVC_BUF_STATE_DONE:
default:
uvc_trace(UVC_TRACE_CAPTURE, [E] Invalid buffer state %u 
(driver bug?).\n, buf-state);
@@ -383,7 +387,7 @@
buf = list_first_entry(queue-mainqueue, struct uvc_buffer, stream);
 
poll_wait(file, buf-wait, wait);
-   if (buf-state == UVC_BUF_STATE_DONE ||
+   if (buf-state == UVC_BUF_STATE_READY ||
buf-state == UVC_BUF_STATE_ERROR)
mask |= POLLIN | POLLRDNORM;
 
@@ -489,6 +493,7 @@
 
spin_lock_irqsave(queue-irqlock, flags);
list_del(buf-queue);
+   buf-state = UVC_BUF_STATE_READY;
if (!list_empty(queue-irqqueue))
nextbuf = list_first_entry(queue-irqqueue, struct uvc_buffer,
   queue);
diff -r c1f376eae978 linux/drivers/media/video/uvc/uvc_video.c
--- a/linux/drivers/media/video/uvc/uvc_video.c Sat Dec 12 18:57:17 2009 +0100
+++ b/linux/drivers/media/video/uvc/uvc_video.c Wed Dec 16 11:47:40 2009 +0100
@@ -578,8 +578,7 @@
uvc_video_decode_end(stream, buf, mem,
urb-iso_frame_desc[i].actual_length);
 
-   if (buf-state == UVC_BUF_STATE_DONE ||
-   buf-state == UVC_BUF_STATE_ERROR)
+   if (buf-state == UVC_BUF_STATE_DONE)
buf = uvc_queue_next_buffer(stream-queue, buf);
}
 }
@@ -637,8 +636,7 @@
if (!stream-bulk.skip_payload  buf != NULL) {
uvc_video_decode_end(stream, buf, stream-bulk.header,
stream-bulk.payload_size);
-   if (buf-state == UVC_BUF_STATE_DONE ||
-   buf-state == UVC_BUF_STATE_ERROR)
+   if (buf-state == UVC_BUF_STATE_DONE)
buf = uvc_queue_next_buffer(stream-queue,
buf);
}
diff -r c1f376eae978 linux/drivers/media/video/uvc/uvcvideo.h
--- a/linux/drivers/media/video/uvc/uvcvideo.h  Sat Dec 12 18:57:17 2009 +0100
+++ b/linux/drivers/media/video/uvc/uvcvideo.h  Wed Dec 16 11:47:40 2009 +0100
@@ -370,7 +370,8 @@
UVC_BUF_STATE_QUEUED= 1,
UVC_BUF_STATE_ACTIVE= 2,
UVC_BUF_STATE_DONE  = 3,
-   UVC_BUF_STATE_ERROR = 4,
+   UVC_BUF_STATE_READY = 4,
+   UVC_BUF_STATE_ERROR = 5,
 };
 
 struct uvc_buffer {


-- 
Regards,

Laurent Pinchart
--
To unsubscribe from this list: send the line 

Re: uvcvideo kernel panic when using libv4l

2009-12-16 Thread Pablo Baena
Yes! This patch worked. So far I got no kernel panic, and image is
correct. Will be testing today to see if something comes up, but so
far it's doing great. Thank you!

On Wed, Dec 16, 2009 at 7:49 AM, Laurent Pinchart
laurent.pinch...@ideasonboard.com wrote:
 Hi Pablo,

 On Wednesday 16 December 2009 07:51:20 Pablo Baena wrote:
 With that patch, libv4l throws an error at some point, no crashes so far
  though:

 libv4l2: error dequeuing buf: Invalid argument
 read error 22, Invalid argument

 Could you please try this updated patch ?

 diff -r c1f376eae978 linux/drivers/media/video/uvc/uvc_queue.c
 --- a/linux/drivers/media/video/uvc/uvc_queue.c Sat Dec 12 18:57:17 2009 +0100
 +++ b/linux/drivers/media/video/uvc/uvc_queue.c Wed Dec 16 11:47:40 2009 +0100
 @@ -59,7 +59,7 @@
  *    returns immediately.
  *
  *    When the buffer is full, the completion handler removes it from the irq
 - *    queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue.
 + *    queue, marks it as ready (UVC_BUF_STATE_READY) and wakes its wait 
 queue.
  *    At that point, any process waiting on the buffer will be woken up. If a
  *    process tries to dequeue a buffer after it has been marked ready, the
  *    dequeing will succeed immediately.
 @@ -196,11 +196,12 @@

        switch (buf-state) {
        case UVC_BUF_STATE_ERROR:
 -       case UVC_BUF_STATE_DONE:
 +       case UVC_BUF_STATE_READY:
                v4l2_buf-flags |= V4L2_BUF_FLAG_DONE;
                break;
        case UVC_BUF_STATE_QUEUED:
        case UVC_BUF_STATE_ACTIVE:
 +       case UVC_BUF_STATE_DONE:
                v4l2_buf-flags |= V4L2_BUF_FLAG_QUEUED;
                break;
        case UVC_BUF_STATE_IDLE:
 @@ -295,13 +296,15 @@
  {
        if (nonblocking) {
                return (buf-state != UVC_BUF_STATE_QUEUED 
 -                       buf-state != UVC_BUF_STATE_ACTIVE)
 +                       buf-state != UVC_BUF_STATE_ACTIVE 
 +                       buf-state != UVC_BUF_STATE_DONE)
                        ? 0 : -EAGAIN;
        }

        return wait_event_interruptible(buf-wait,
                buf-state != UVC_BUF_STATE_QUEUED 
 -               buf-state != UVC_BUF_STATE_ACTIVE);
 +               buf-state != UVC_BUF_STATE_ACTIVE 
 +               buf-state != UVC_BUF_STATE_DONE);
  }

  /*
 @@ -341,13 +344,14 @@
                uvc_trace(UVC_TRACE_CAPTURE, [W] Corrupted data 
                        (transmission error).\n);
                ret = -EIO;
 -       case UVC_BUF_STATE_DONE:
 +       case UVC_BUF_STATE_READY:
                buf-state = UVC_BUF_STATE_IDLE;
                break;

        case UVC_BUF_STATE_IDLE:
        case UVC_BUF_STATE_QUEUED:
        case UVC_BUF_STATE_ACTIVE:
 +       case UVC_BUF_STATE_DONE:
        default:
                uvc_trace(UVC_TRACE_CAPTURE, [E] Invalid buffer state %u 
                        (driver bug?).\n, buf-state);
 @@ -383,7 +387,7 @@
        buf = list_first_entry(queue-mainqueue, struct uvc_buffer, stream);

        poll_wait(file, buf-wait, wait);
 -       if (buf-state == UVC_BUF_STATE_DONE ||
 +       if (buf-state == UVC_BUF_STATE_READY ||
            buf-state == UVC_BUF_STATE_ERROR)
                mask |= POLLIN | POLLRDNORM;

 @@ -489,6 +493,7 @@

        spin_lock_irqsave(queue-irqlock, flags);
        list_del(buf-queue);
 +       buf-state = UVC_BUF_STATE_READY;
        if (!list_empty(queue-irqqueue))
                nextbuf = list_first_entry(queue-irqqueue, struct uvc_buffer,
                                           queue);
 diff -r c1f376eae978 linux/drivers/media/video/uvc/uvc_video.c
 --- a/linux/drivers/media/video/uvc/uvc_video.c Sat Dec 12 18:57:17 2009 +0100
 +++ b/linux/drivers/media/video/uvc/uvc_video.c Wed Dec 16 11:47:40 2009 +0100
 @@ -578,8 +578,7 @@
                uvc_video_decode_end(stream, buf, mem,
                        urb-iso_frame_desc[i].actual_length);

 -               if (buf-state == UVC_BUF_STATE_DONE ||
 -                   buf-state == UVC_BUF_STATE_ERROR)
 +               if (buf-state == UVC_BUF_STATE_DONE)
                        buf = uvc_queue_next_buffer(stream-queue, buf);
        }
  }
 @@ -637,8 +636,7 @@
                if (!stream-bulk.skip_payload  buf != NULL) {
                        uvc_video_decode_end(stream, buf, stream-bulk.header,
                                stream-bulk.payload_size);
 -                       if (buf-state == UVC_BUF_STATE_DONE ||
 -                           buf-state == UVC_BUF_STATE_ERROR)
 +                       if (buf-state == UVC_BUF_STATE_DONE)
                                buf = uvc_queue_next_buffer(stream-queue,
                                                            buf);
                }
 diff -r c1f376eae978 linux/drivers/media/video/uvc/uvcvideo.h
 --- a/linux/drivers/media/video/uvc/uvcvideo.h  Sat Dec 12 18:57:17 2009 +0100
 +++ b/linux/drivers/media/video/uvc/uvcvideo.h  Wed Dec 16 11:47:40 2009 +0100
 @@ -370,7 +370,8 @@
        UVC_BUF_STATE_QUEUED   

Re: uvcvideo kernel panic when using libv4l

2009-12-15 Thread Laurent Pinchart
Hi Leandro and Pablo,

could you please try the following patch ? It closes a race window that I
believe could be at the core of your kernel panic.

diff -r c1f376eae978 linux/drivers/media/video/uvc/uvc_queue.c
--- a/linux/drivers/media/video/uvc/uvc_queue.c Sat Dec 12 18:57:17 2009 +0100
+++ b/linux/drivers/media/video/uvc/uvc_queue.c Wed Dec 16 01:10:21 2009 +0100
@@ -59,7 +59,7 @@
  *returns immediately.
  *
  *When the buffer is full, the completion handler removes it from the irq
- *queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue.
+ *queue, marks it as ready (UVC_BUF_STATE_READY) and wakes its wait queue.
  *At that point, any process waiting on the buffer will be woken up. If a
  *process tries to dequeue a buffer after it has been marked ready, the
  *dequeing will succeed immediately.
@@ -196,11 +196,12 @@
 
switch (buf-state) {
case UVC_BUF_STATE_ERROR:
-   case UVC_BUF_STATE_DONE:
+   case UVC_BUF_STATE_READY:
v4l2_buf-flags |= V4L2_BUF_FLAG_DONE;
break;
case UVC_BUF_STATE_QUEUED:
case UVC_BUF_STATE_ACTIVE:
+   case UVC_BUF_STATE_DONE:
v4l2_buf-flags |= V4L2_BUF_FLAG_QUEUED;
break;
case UVC_BUF_STATE_IDLE:
@@ -341,13 +342,14 @@
uvc_trace(UVC_TRACE_CAPTURE, [W] Corrupted data 
(transmission error).\n);
ret = -EIO;
-   case UVC_BUF_STATE_DONE:
+   case UVC_BUF_STATE_READY:
buf-state = UVC_BUF_STATE_IDLE;
break;
 
case UVC_BUF_STATE_IDLE:
case UVC_BUF_STATE_QUEUED:
case UVC_BUF_STATE_ACTIVE:
+   case UVC_BUF_STATE_DONE:
default:
uvc_trace(UVC_TRACE_CAPTURE, [E] Invalid buffer state %u 
(driver bug?).\n, buf-state);
@@ -383,7 +385,7 @@
buf = list_first_entry(queue-mainqueue, struct uvc_buffer, stream);
 
poll_wait(file, buf-wait, wait);
-   if (buf-state == UVC_BUF_STATE_DONE ||
+   if (buf-state == UVC_BUF_STATE_READY ||
buf-state == UVC_BUF_STATE_ERROR)
mask |= POLLIN | POLLRDNORM;
 
@@ -489,6 +491,7 @@
 
spin_lock_irqsave(queue-irqlock, flags);
list_del(buf-queue);
+   buf-state = UVC_BUF_STATE_READY;
if (!list_empty(queue-irqqueue))
nextbuf = list_first_entry(queue-irqqueue, struct uvc_buffer,
   queue);
diff -r c1f376eae978 linux/drivers/media/video/uvc/uvc_video.c
--- a/linux/drivers/media/video/uvc/uvc_video.c Sat Dec 12 18:57:17 2009 +0100
+++ b/linux/drivers/media/video/uvc/uvc_video.c Wed Dec 16 01:10:21 2009 +0100
@@ -578,8 +578,7 @@
uvc_video_decode_end(stream, buf, mem,
urb-iso_frame_desc[i].actual_length);
 
-   if (buf-state == UVC_BUF_STATE_DONE ||
-   buf-state == UVC_BUF_STATE_ERROR)
+   if (buf-state == UVC_BUF_STATE_DONE)
buf = uvc_queue_next_buffer(stream-queue, buf);
}
 }
@@ -637,8 +636,7 @@
if (!stream-bulk.skip_payload  buf != NULL) {
uvc_video_decode_end(stream, buf, stream-bulk.header,
stream-bulk.payload_size);
-   if (buf-state == UVC_BUF_STATE_DONE ||
-   buf-state == UVC_BUF_STATE_ERROR)
+   if (buf-state == UVC_BUF_STATE_DONE)
buf = uvc_queue_next_buffer(stream-queue,
buf);
}
diff -r c1f376eae978 linux/drivers/media/video/uvc/uvcvideo.h
--- a/linux/drivers/media/video/uvc/uvcvideo.h  Sat Dec 12 18:57:17 2009 +0100
+++ b/linux/drivers/media/video/uvc/uvcvideo.h  Wed Dec 16 01:10:21 2009 +0100
@@ -370,7 +370,8 @@
UVC_BUF_STATE_QUEUED= 1,
UVC_BUF_STATE_ACTIVE= 2,
UVC_BUF_STATE_DONE  = 3,
-   UVC_BUF_STATE_ERROR = 4,
+   UVC_BUF_STATE_READY = 4,
+   UVC_BUF_STATE_ERROR = 5,
 };
 
 struct uvc_buffer {

-- 
Regards,

Laurent Pinchart
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: uvcvideo kernel panic when using libv4l

2009-12-15 Thread Pablo Baena
With that patch, libv4l throws an error at some point, no crashes so far though:

libv4l2: error dequeuing buf: Invalid argument
read error 22, Invalid argument

On Tue, Dec 15, 2009 at 9:12 PM, Laurent Pinchart
laurent.pinch...@ideasonboard.com wrote:
 Hi Leandro and Pablo,

 could you please try the following patch ? It closes a race window that I
 believe could be at the core of your kernel panic.

 diff -r c1f376eae978 linux/drivers/media/video/uvc/uvc_queue.c
 --- a/linux/drivers/media/video/uvc/uvc_queue.c Sat Dec 12 18:57:17 2009 +0100
 +++ b/linux/drivers/media/video/uvc/uvc_queue.c Wed Dec 16 01:10:21 2009 +0100
 @@ -59,7 +59,7 @@
  *    returns immediately.
  *
  *    When the buffer is full, the completion handler removes it from the irq
 - *    queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue.
 + *    queue, marks it as ready (UVC_BUF_STATE_READY) and wakes its wait 
 queue.
  *    At that point, any process waiting on the buffer will be woken up. If a
  *    process tries to dequeue a buffer after it has been marked ready, the
  *    dequeing will succeed immediately.
 @@ -196,11 +196,12 @@

        switch (buf-state) {
        case UVC_BUF_STATE_ERROR:
 -       case UVC_BUF_STATE_DONE:
 +       case UVC_BUF_STATE_READY:
                v4l2_buf-flags |= V4L2_BUF_FLAG_DONE;
                break;
        case UVC_BUF_STATE_QUEUED:
        case UVC_BUF_STATE_ACTIVE:
 +       case UVC_BUF_STATE_DONE:
                v4l2_buf-flags |= V4L2_BUF_FLAG_QUEUED;
                break;
        case UVC_BUF_STATE_IDLE:
 @@ -341,13 +342,14 @@
                uvc_trace(UVC_TRACE_CAPTURE, [W] Corrupted data 
                        (transmission error).\n);
                ret = -EIO;
 -       case UVC_BUF_STATE_DONE:
 +       case UVC_BUF_STATE_READY:
                buf-state = UVC_BUF_STATE_IDLE;
                break;

        case UVC_BUF_STATE_IDLE:
        case UVC_BUF_STATE_QUEUED:
        case UVC_BUF_STATE_ACTIVE:
 +       case UVC_BUF_STATE_DONE:
        default:
                uvc_trace(UVC_TRACE_CAPTURE, [E] Invalid buffer state %u 
                        (driver bug?).\n, buf-state);
 @@ -383,7 +385,7 @@
        buf = list_first_entry(queue-mainqueue, struct uvc_buffer, stream);

        poll_wait(file, buf-wait, wait);
 -       if (buf-state == UVC_BUF_STATE_DONE ||
 +       if (buf-state == UVC_BUF_STATE_READY ||
            buf-state == UVC_BUF_STATE_ERROR)
                mask |= POLLIN | POLLRDNORM;

 @@ -489,6 +491,7 @@

        spin_lock_irqsave(queue-irqlock, flags);
        list_del(buf-queue);
 +       buf-state = UVC_BUF_STATE_READY;
        if (!list_empty(queue-irqqueue))
                nextbuf = list_first_entry(queue-irqqueue, struct uvc_buffer,
                                           queue);
 diff -r c1f376eae978 linux/drivers/media/video/uvc/uvc_video.c
 --- a/linux/drivers/media/video/uvc/uvc_video.c Sat Dec 12 18:57:17 2009 +0100
 +++ b/linux/drivers/media/video/uvc/uvc_video.c Wed Dec 16 01:10:21 2009 +0100
 @@ -578,8 +578,7 @@
                uvc_video_decode_end(stream, buf, mem,
                        urb-iso_frame_desc[i].actual_length);

 -               if (buf-state == UVC_BUF_STATE_DONE ||
 -                   buf-state == UVC_BUF_STATE_ERROR)
 +               if (buf-state == UVC_BUF_STATE_DONE)
                        buf = uvc_queue_next_buffer(stream-queue, buf);
        }
  }
 @@ -637,8 +636,7 @@
                if (!stream-bulk.skip_payload  buf != NULL) {
                        uvc_video_decode_end(stream, buf, stream-bulk.header,
                                stream-bulk.payload_size);
 -                       if (buf-state == UVC_BUF_STATE_DONE ||
 -                           buf-state == UVC_BUF_STATE_ERROR)
 +                       if (buf-state == UVC_BUF_STATE_DONE)
                                buf = uvc_queue_next_buffer(stream-queue,
                                                            buf);
                }
 diff -r c1f376eae978 linux/drivers/media/video/uvc/uvcvideo.h
 --- a/linux/drivers/media/video/uvc/uvcvideo.h  Sat Dec 12 18:57:17 2009 +0100
 +++ b/linux/drivers/media/video/uvc/uvcvideo.h  Wed Dec 16 01:10:21 2009 +0100
 @@ -370,7 +370,8 @@
        UVC_BUF_STATE_QUEUED    = 1,
        UVC_BUF_STATE_ACTIVE    = 2,
        UVC_BUF_STATE_DONE      = 3,
 -       UVC_BUF_STATE_ERROR     = 4,
 +       UVC_BUF_STATE_READY     = 4,
 +       UVC_BUF_STATE_ERROR     = 5,
  };

  struct uvc_buffer {

 --
 Regards,

 Laurent Pinchart




-- 
Not possessing the gift of reflection, a dog does not know that he
does not know, and does not understand that he understands nothing;
we, on the other hand, are aware of both. If we behave otherwise, it
is from stupidity, or else from self-deception, to preserve our peace
of mind.
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: uvcvideo kernel panic when using libv4l

2009-12-13 Thread Laurent Pinchart
Hi Costantino,

thanks for investigating the problem.

On Sunday 13 December 2009 08:48:24 lcostant...@gmail.com wrote:
 There seems to be a 'kind of race', when queue and dequeue buffer as in
 capture.c (attached on the first mail) it's used.
 
 This could be easily detected on a kernel with DEBUG_LIST enabled. The
 poison values will be shown on the oops.

Indeed, your analysis seems correct.

 This is a test patch only..
 
 The oops its triggered when something like this happens:
 
suppose X=1 (v4l2_buf-index)
uvc_queue_next_buffer-
   buf = [buf_index_X]
* in the middle, the same buffer is attached to the list...

How would that happen ? I can see a tiny race condition in the code, but I'm 
not sure it could get triggered in practice.

When the interrupt handler marks the buffer as done, a userspace application 
could then dequeue and requeue the buffer before the interrupt handler calls 
uvc_queue_next_buffer() to remove from the irqqueue list. That would require 
an SMP system, and a userspace application running fast enough to call both 
DQBUF and QBUF between the time the buffer is marked as done and the time the 
buffer is removed from the list. Theoretically possible, but highly 
improbable.

* uvc_queue_next_buffer  calls  list_del(buf-queue)
* Now prev and next from buf-queue are poisoned
* next uvc_queue_next_buffer will fetch the same buffer index, and
  call list_del again, triggering the oops.

If the buffer can indeed end up back in the list before being dequeued, I 
agree with your analysis.

 I can only reproduce this using the capture.c attached, that should
 return 0 after an -EAGAIN and not 'continue the loop'. In fact, after
 this little thest patch , the capture.c shouldn't work anymore, but
 svv.c (from jmoinef) , will work as expected using the read method.

I can't reproduce the problem here so I can't investigate. Could you find out 
how the race condition is triggered ?

 I really, didn't have time to like if this can be fixed getting some
 of the lokcs earlier, so , this patch it just for testing if the oops
 still happens with you. It just added a new 'state' , if a buffer is
 marked as done but , ihave not been dequeued, in the sense of
 list_del have been called, then -EINVAL will be returned. This should
 the the common behavior, but for those reasons, it's not ben returned.
 
 Also, trace shouldn't be used to trigger the buf, since it's during
 interrupt context, the delays added by the printk, make it more
 difficult to trigger.
 
 Laurent, could you check if something of this make sense, or i am just
 talking bs?

States are not bit flags, so UVC_BUF_STATE_DONE|UVC_BUF_STATE_UNQUEUED will 
actually be equal to UVC_BUF_STATE_UNQUEUED. No sure if that's what you 
wanted.

 I tested it on ID 064e:a101 Suyin Corp. Laptop integrated WebCam (acer 5420)
 
 PD: Note that this patch apply only to isoc decode. In case of a
 proposed apply, decode_bulk, and isight should be taken in account too
 when checking the buf-state.
 
 Signed-off-by: Costantino Leandro lcostant...@gmail.com
 ---
 
 diff -Nru gspca-e16961fe157d/linux/drivers/media/video/uvc/uvc_queue.c
  gspca-dev//linux/drivers/media/video/uvc/uvc_queue.c ---
  gspca-e16961fe157d/linux/drivers/media/video/uvc/uvc_queue.c 2009-12-02
  12:39:53.0 -0500 +++
  gspca-dev//linux/drivers/media/video/uvc/uvc_queue.c 2009-12-13
  04:06:44.0 -0500 @@ -197,6 +197,7 @@
   switch (buf-state) {
   case UVC_BUF_STATE_ERROR:
   case UVC_BUF_STATE_DONE:
 + case (UVC_BUF_STATE_DONE | UVC_BUF_STATE_UNQUEUED):
   v4l2_buf-flags |= V4L2_BUF_FLAG_DONE;
   break;
   case UVC_BUF_STATE_QUEUED:
 @@ -341,10 +342,13 @@
   uvc_trace(UVC_TRACE_CAPTURE, [W] Corrupted data 
   (transmission error).\n);
   ret = -EIO;
 - case UVC_BUF_STATE_DONE:
 + case (UVC_BUF_STATE_DONE|UVC_BUF_STATE_UNQUEUED):
 + uvc_trace(UVC_TRACE_CAPTURE, [I] Buffer %u completed.
 +  Ready for 'reuse'.\n, v4l2_buf-index);
   buf-state = UVC_BUF_STATE_IDLE;
   break;
 -
 + case UVC_BUF_STATE_DONE:
 + break;;
   case UVC_BUF_STATE_IDLE:
   case UVC_BUF_STATE_QUEUED:
   case UVC_BUF_STATE_ACTIVE:
 @@ -383,8 +387,8 @@
   buf = list_first_entry(queue-mainqueue, struct uvc_buffer, stream);
 
   poll_wait(file, buf-wait, wait);
 - if (buf-state == UVC_BUF_STATE_DONE ||
 - buf-state == UVC_BUF_STATE_ERROR)
 + if (buf-state == (UVC_BUF_STATE_DONE | UVC_BUF_STATE_UNQUEUED)
 + || buf-state == UVC_BUF_STATE_ERROR)
   mask |= POLLIN | POLLRDNORM;
 
  done:
 @@ -489,7 +493,9 @@
 
   spin_lock_irqsave(queue-irqlock, flags);
   list_del(buf-queue);
 - if (!list_empty(queue-irqqueue))
 +
 + buf-state = (UVC_BUF_STATE_DONE | UVC_BUF_STATE_UNQUEUED);
 + if (!list_empty(queue-irqqueue))
   

Re: uvcvideo kernel panic when using libv4l

2009-12-10 Thread Laurent Pinchart
Hi Pablo,

On Monday 07 December 2009 18:18:11 Pablo Baena wrote:
 I get a kernel panic when running the attached sample code.
 
 I run it as:
 
 $ gcc capture.c -o capture
 $ export LD_PRELOAD=/usr/lib/libv4l/v4l2convert.so
 $ ./capture -d/dev/video0 -c1000 -r
 
 -r tells it to capture using read(), which libv4l emulates.
 
 In the example code, I use read() to fetch from the webcam directly,
 without using select() to wait for a frame. In the v4l documentation,
 it states that read() should block until it has a new frame available.
 
 This is a Bus 002 Device 005: ID 0c45:62c0 Microdia Sonix USB 2.0 Camera.
 
 I can't capture the kernel panic because everything hangs and I have
 no kernel debugger to try to get that info. I attach a poor quality
 image taken with a webcam from the screen. I even tried having a
 vmware virtual machine to try to better capture the panic, but in the
 virtual machine it doesn't hang.
 
 This is Ubuntu 9.10, Linux pablo-laptop 2.6.31-16-generic #52-Ubuntu
 SMP Thu Dec 3 22:00:22 UTC 2009 i686 GNU/Linux.
 
 But I got reports that the same camera on Debian 5.3 is also panicking.
 
 Please advice if you need more information to solve this problem.

I can't reproduce the problem here (with another camera).

To investigate I will need a copy of the source code and binary kernel module 
for the uvcvideo driver running on your system as well as a complete complete 
backtrace.

-- 
Regards,

Laurent Pinchart
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: uvcvideo kernel panic when using libv4l

2009-12-10 Thread Pablo Baena
Can you tell me how to obtain such backtrace? This is a hard panic and
I don't know how to obtain a backtrace, since the keyboard gets
unresponsive.

On Thu, Dec 10, 2009 at 11:19 AM, Laurent Pinchart
laurent.pinch...@ideasonboard.com wrote:
 Hi Pablo,

 On Monday 07 December 2009 18:18:11 Pablo Baena wrote:
 I get a kernel panic when running the attached sample code.

 I run it as:

 $ gcc capture.c -o capture
 $ export LD_PRELOAD=/usr/lib/libv4l/v4l2convert.so
 $ ./capture -d/dev/video0 -c1000 -r

 -r tells it to capture using read(), which libv4l emulates.

 In the example code, I use read() to fetch from the webcam directly,
 without using select() to wait for a frame. In the v4l documentation,
 it states that read() should block until it has a new frame available.

 This is a Bus 002 Device 005: ID 0c45:62c0 Microdia Sonix USB 2.0 Camera.

 I can't capture the kernel panic because everything hangs and I have
 no kernel debugger to try to get that info. I attach a poor quality
 image taken with a webcam from the screen. I even tried having a
 vmware virtual machine to try to better capture the panic, but in the
 virtual machine it doesn't hang.

 This is Ubuntu 9.10, Linux pablo-laptop 2.6.31-16-generic #52-Ubuntu
 SMP Thu Dec 3 22:00:22 UTC 2009 i686 GNU/Linux.

 But I got reports that the same camera on Debian 5.3 is also panicking.

 Please advice if you need more information to solve this problem.

 I can't reproduce the problem here (with another camera).

 To investigate I will need a copy of the source code and binary kernel module
 for the uvcvideo driver running on your system as well as a complete complete
 backtrace.

 --
 Regards,

 Laurent Pinchart




-- 
Not possessing the gift of reflection, a dog does not know that he
does not know, and does not understand that he understands nothing;
we, on the other hand, are aware of both. If we behave otherwise, it
is from stupidity, or else from self-deception, to preserve our peace
of mind.
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: uvcvideo kernel panic when using libv4l

2009-12-10 Thread Laurent Pinchart
On Thursday 10 December 2009 16:26:19 Pablo Baena wrote:
 Can you tell me how to obtain such backtrace? This is a hard panic and
 I don't know how to obtain a backtrace, since the keyboard gets
 unresponsive.

Once the kernel crashes in interrupt context there's not much you can do. One 
solution would be to write the backtrace down, but that's a bit tedious :-)

Another solution, if your computer has a serial port, is to activate a serial 
console and hook it up to another computer where you will be able to capture 
the oops.

-- 
Regards,

Laurent Pinchart
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html