Re: [PATCH 0/3] usb: gadget: uvc: allocate requests based on frame interval length and buffersize

From: Alan Stern
Date: Wed May 22 2024 - 14:58:33 EST


On Wed, May 22, 2024 at 07:37:59PM +0200, Michael Grzeschik wrote:
> On Wed, May 22, 2024 at 05:17:02PM +0000, Thinh Nguyen wrote:
> > I agree. The dwc3 driver has this workaround to somewhat work with the
> > UVC. This behavior is not something the controller expected, and this
> > workaround should not be a common behavior for different function
> > driver/protocol. Since this behavior was added a long time ago, it will
> > remain the default behavior in dwc3 to avoid regression with UVC (at
> > least until the UVC is changed). However, it would be nice for UVC to
> > not rely on this.
>
> With "this" you mean exactly the following commit, right?
>
> (f5e46aa4 usb: dwc3: gadget: when the started list is empty stop the active xfer)
>
> When we start questioning this, then lets dig deeper here.
>
> With the fast datarate of at least usb superspeed shouldn't they not all
> completely work asynchronous with their in flight trbs?
>
> In my understanding this validates that, with at least superspeed we are
> unlikely to react fast enough to maintain a steady isoc dataflow, since
> the driver above has to react to errors in the processing context.
>
> This runs the above patch (f5e46aa4) a gadget independent solution
> which has nothing to do with uvc in particular IMHO.
>
> How do other controllers and their drivers work?

You should think of isochronous transfer requests as a pipeline flowing
from the function driver to the UDC driver. As long as the pipeline
never becomes empty, transfers will occur with the desired timing: one
packet (ignoring high-bandwidth issues) per isochronous interval.

But if the pipeline does become empty, because the function driver
doesn't submit requests to the UDC driver quickly enough, the behavior
is undetermined. Obviously no data can be sent before the next request
is submitted. And even if the next request is submitted before the next
time interval expires, the UDC driver might delay transferring the
request's data until a later time interval. Or it might not. In short,
when the function driver does submit its next request, there's no way to
know in which interval its data will get sent to the host. Furthermore,
there's no way in the gadget framework for the function driver to ask
that the request be sent in a particular transfer window.

This means that function drivers should do their best to make sure the
pipeline never becomes empty, that there always is at least one request
in progress at all times. Even if this requires submitting zero-length
requests because the necessary data isn't available yet.

Remember, isochronous transfers are meant only to be a best-effort
attempt at low-latency data delivery, without guarantees (other than a
reserved amount of bandwidth). If a packet gets lost or dropped from
time to time, whether because of transmission errors or because the data
source was unable to keep up, it shouldn't matter very much in the end.
The receiver (i.e., the host) should be able to recover, resynchronize,
and move on.

Alan Stern