Re: dwc2 gadget rejecting new AIO transfer when bus is suspended

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

 



Hello Artur,

On Fri, 25 Dec 2020 10:56:02 +0000, Artur Petrosyan <Arthur.Petrosyan@xxxxxxxxxxxx> wrote:
> According your debug log core enters suspend on receiving an 
> GINTSTS_ErlySusp interrupt. It means that the driver goes to L2 state 
> (suspend). In suspend mode accepting and processing EP requests can lead 
> to unexpected behavior. That is why the driver rejects EP request with 
> -EAGAIN.
> 
> As core may use power saving modes which are initiated by the Suspend 
> interrupt, then in any suspend mode whether it is hibernation or partial 
> power down the core registers are not available. This is why we avoid to 
> get new EP requests.

This is my understanding from reading the commit history, yes.

But from userland's point of view this causes a weird situation:
- sequence 1:
  - userland submits buffer (ex: to receive the next host request)
  - UDC is suspended
  - UDC is awoken by host initiating a transfer
  Result: the AIO completes successfully, the suspension was completely
  invisible to userland, and I'm happy.
- sequence 2:
  - UDC is suspended
  - userland submits buffer (ex: to receive the next host request)
  Result: the AIO completes with an error, the suspension got in the
  way, and I'm confused about what I need to make my code do to
  recover: should I change my IO completion codepath so that it
  resubmits any EAGAIN completion, hoping to catch the UDC at a time it
  is awoken so the AIO finally sticks and everything can sleep until an
  actual transfer completion ?

I do not know if it makes sense from a kernel point of view, but would
it be possible for the dwc2 module to sit on the AIO requests while the
controller is suspended, and submit them when it wakes up rather than
failing them immediately and sending them back to userland ?
I expect that this code actually knows (without polling) when the
controller is awoken.

> The main question is why on usb bus seen ErlySusp interrupt. Is it 
> initiated by host? If yes, why?

My pre-USB-analyser guess is it would just be the normal USB-idle-to-
bus-suspend behaviour. Besides device enumeration, the host is not
accessing the device right after it is plugged in, so there should be
no reason to keep the bus ticking.

Unless there is something fundamentally wrong with the suspension
happening at all, my biggest issue is the poor userland-level usability
*if* suspension happens, and the race-condition this behaviour creates
(IO cannot be submitted before the UDC is bound to the gadget, and IO
cannot be submitted after either if it happens after an external event,
leaving only a short time window where it works).

If I am missing anything there which would allow userland to guarantee
keeping the UDC awoken so the transfers would stay in-queue, please do
tell me.

Regards,
-- 
Vincent Pelletier



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux