All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Grzeschik <m.grzeschik@pengutronix.de>
To: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org
Subject: duplicate requests on host side while streaming via uvcvideo gadget
Date: Tue, 6 Feb 2024 00:40:28 +0100	[thread overview]
Message-ID: <ZcFx7P30Su_Mx4AV@pengutronix.de> (raw)

[-- Attachment #1: Type: text/plain, Size: 7219 bytes --]

Hi Thinh

I found some strange situation while streaming via uvc-gadget to some
usb host. It happens when some requests are missed due to higher load on
the gadget machine. In some cases some requests will reach the host
twice. In my special case, I added the following changes [1] for the
host and gadget side.

When applying the patches you will find all requests marked as errors on
the host and gadget side reported. However, the odd thing is that the
error counter on the host side will rise higher than the number of
requests we have actually marked as errornous on the gadget side. You
check the number of errors found on the host by looking in the
statistics and compare it with the numer of requests that are actually
marked with UVC_STREAM_ERR.

[1] applied hunks:

diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h
index 6bdcf3bdd62a9..63515fc949880 100644
--- a/drivers/usb/gadget/function/uvc.h
+++ b/drivers/usb/gadget/function/uvc.h
@@ -91,6 +91,8 @@ struct uvc_video {
         struct work_struct pump;
         struct workqueue_struct *async_wq;

+       int errorcount;
+
         /* Frame parameters */
         u8 bpp;
         u32 fcc;

diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
index eb1f7cee4a0af..f45dd53fde7ef 100644
--- a/drivers/usb/gadget/function/uvc_video.c
+++ b/drivers/usb/gadget/function/uvc_video.c
@@ -35,6 +35,12 @@ uvc_video_encode_header(struct uvc_video *video, struct uvc_buffer *buf,

         data[1] = UVC_STREAM_EOH | video->fid;

+       if (video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE) {
+               video->errorcount++;
+               printk("dropping frame! %d\n", video->errorcount);
+               data[1] |= UVC_STREAM_ERR;
+       }
+
         if (video->queue.buf_used == 0 && ts.tv_sec) {
                 /* dwClockFrequency is 48 MHz */
                 u32 pts = ((u64)ts.tv_sec * USEC_PER_SEC + ts.tv_nsec / NSEC_PER_USEC) * 48;

@@ -47,6 +47,8 @@ uvc_video_encode_header(struct uvc_video *video, struct uvc_buffer *buf,
  
                 data[1] |= UVC_STREAM_PTS;
                 put_unaligned_le32(pts, &data[pos]);
+               if (data[1] & UVC_STREAM_ERR)
+                       trace_printk("PTS: %u\n", data[pos]);
                 pos += 4;
         }
  
@@ -60,6 +62,10 @@ uvc_video_encode_header(struct uvc_video *video, struct uvc_buffer *buf,
                 data[1] |= UVC_STREAM_SCR;
                 put_unaligned_le32(stc, &data[pos]);
                 put_unaligned_le16(sof, &data[pos+4]);
+               if (data[1] & UVC_STREAM_ERR) {
+                       trace_printk("SCR: %u\n", data[pos]);
+                       trace_printk("SCR: %hu\n", data[pos+4]);
+               }
                 pos += 6;
         }
  

@@ -731,6 +734,7 @@ int uvcg_video_enable(struct uvc_video *video)
         struct usb_gadget *gadget = cdev->gadget;
         int ret;

+       video->errorcount = 0;
         if (video->ep == NULL) {
                 uvcg_info(&video->uvc->func,
                           "Video enable failed, device is uninitialized.\n");

diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 28dde08ec6c5d..40eafe43d1888 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -916,8 +916,24 @@ static void uvc_video_stats_decode(struct uvc_streaming *stream,
         if (len <= header_size)
                 stream->stats.frame.nb_empty++;

-       if (data[1] & UVC_STREAM_ERR)
+       if (data[1] & UVC_STREAM_ERR) {
                 stream->stats.frame.nb_errors++;
+               printk("error on uvc package!\n");
+               if (data[1] & UVC_STREAM_PTS) {
+                       printk("PTS: %u\n", data[2]);
+                       if (data[1] & UVC_STREAM_SCR) {
+                               printk("SCR: %u\n", data[6]);
+                               printk("SCR: %hu\n", data[10]);
+                       }
+               } else {
+                       if (data[1] & UVC_STREAM_SCR) {
+                               printk("SCR: %u\n", data[2]);
+                               printk("SCR: %hu\n", data[6]);
+                       }
+               }
+
+
+       }
  }

-- Host:

[ 1769.213387] error on uvc package!
[ 1769.213396] PTS: 16
[ 1769.213400] SCR: 64
[ 1769.213402] SCR: 229

[ 1769.461386] error on uvc package!
[ 1769.461394] PTS: 96
[ 1769.461398] SCR: 80
[ 1769.461401] SCR: 33

[ 1769.461405] error on uvc package! <- duplicate
[ 1769.461408] PTS: 96
[ 1769.461410] SCR: 80
[ 1769.461413] SCR: 33

[ 1769.657405] error on uvc package!
[ 1769.657442] PTS: 224
[ 1769.657449] SCR: 64
[ 1769.657453] SCR: 81

[ 1769.657460] error on uvc package! <- duplicate
[ 1769.657465] PTS: 224
[ 1769.657470] SCR: 64
[ 1769.657476] SCR: 81

[ 1779.525368] error on uvc package!
[ 1779.525374] PTS: 128
[ 1779.525378] SCR: 224
[ 1779.525380] SCR: 157

[ 1784.637359] error on uvc package!
[ 1784.637367] PTS: 0
[ 1784.637371] SCR: 208
[ 1784.637374] SCR: 89

[ 1784.825357] error on uvc package!
[ 1784.825394] PTS: 224
[ 1784.825401] SCR: 192
[ 1784.825406] SCR: 63

[ 1784.841362] error on uvc package!
[ 1784.841394] PTS: 144
[ 1784.841403] SCR: 48
[ 1784.841410] SCR: 186

[ 1784.841418] error on uvc package! <- duplicate
[ 1784.841424] PTS: 144
[ 1784.841430] SCR: 48
[ 1784.841436] SCR: 186

host$ grep errors /sys/kernel/debug/usb/uvcvideo/*/stats
/sys/kernel/debug/usb/uvcvideo/4-81-1/stats:errors:  10


-- Gadget:

[  126.826517] dropping frame! 1
[  126.829658] PTS: 16
[  126.831761] SCR: 64
[  126.833858] SCR: 229

[  127.090069] dropping frame! 2
[  127.093059] PTS: 96
[  127.095164] SCR: 80
[  127.097261] SCR: 33

[  127.288045] dropping frame! 3
[  127.291041] PTS: 224
[  127.293233] SCR: 64
[  127.295330] SCR: 81

[  137.153499] dropping frame! 4
[  137.156494] PTS: 128
[  137.158687] SCR: 224
[  137.160871] SCR: 157

[  142.265135] dropping frame! 5
[  142.268131] PTS: 0
[  142.270148] SCR: 208
[  142.272332] SCR: 89

[  142.453636] dropping frame! 6
[  142.456634] PTS: 224
[  142.458825] SCR: 192
[  142.461009] SCR: 63

[  142.469131] dropping frame! 7
[  142.472118] PTS: 144
[  142.474310] SCR: 48
[  142.476407] SCR: 186

Now I am totally unsure what could cause such error, but would expect
the issue to be somewhere in the gadget driver and the mapped trb memory
content. For the uvc_video layer, I compared and tested the enqueued
request list for duplicates but could not find any. I also reverted all
recent patches that changed request handling in the past year. I still
find these request duplicates on the host side show up.

Any Ideas?

Regards,
Michael

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

             reply	other threads:[~2024-02-05 23:40 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-05 23:40 Michael Grzeschik [this message]
2024-02-06  3:23 ` duplicate requests on host side while streaming via uvcvideo gadget Thinh Nguyen
2024-02-06 21:30   ` Michael Grzeschik
2024-02-07 13:04     ` Kieran Bingham
2024-02-07 13:10       ` Michael Grzeschik

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=ZcFx7P30Su_Mx4AV@pengutronix.de \
    --to=m.grzeschik@pengutronix.de \
    --cc=Thinh.Nguyen@synopsys.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.