Re: usb_ep_{dis,en}able() calling context (was: Re: [PATCH 2/3] usb: dwc3: gadget: wait for End Transfer to complete)

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

 



Hi,

Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> writes:
>> Baolin Wang <baolin.wang@xxxxxxxxxx> writes:
>> >> Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx> writes:
>> >>> Instead of just delaying for 100us, we should
>> >>> actually wait for End Transfer Command Complete
>> >>> interrupt before moving on. Note that this should
>> >>> only be done if we're dealing with one of the core
>> >>> revisions that actually require the interrupt before
>> >>> moving on.
>> >>>
>> >>> Reported-by: Baolin Wang <baolin.wang@xxxxxxxxxx>
>> >>> Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx>
>> >>
>> >> I've updated this one in order to fix the comment we had about delaying
>> >> 100us. No further changes were made, only the comment. Here it is:
>> >>
>> >> 8<------------------------------------------------------------------------
>> >> From f3fa94f3171709f787a30e3c5ce69a668960b66e Mon Sep 17 00:00:00 2001
>> >> From: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx>
>> >> Date: Thu, 13 Oct 2016 14:09:47 +0300
>> >> Subject: [PATCH v2] usb: dwc3: gadget: wait for End Transfer to complete
>> >>
>> >> Instead of just delaying for 100us, we should
>> >> actually wait for End Transfer Command Complete
>> >> interrupt before moving on. Note that this should
>> >> only be done if we're dealing with one of the core
>> >> revisions that actually require the interrupt before
>> >> moving on.
>> >>
>> >> Reported-by: Baolin Wang <baolin.wang@xxxxxxxxxx>
>> >> Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx>
>> >
>> > From my testing, there are still some problems caused by the nested
>> > lock, at lease I found 2 functions will issue the usb_ep_disable()
>> > function with spinlock:
>> 
>> Thanks for testing. Seems like I really need to revisit locking in the
>> entire gadget API. In either case, we need to have a larger discussion
>> about this situation.
>> 
>> IMO, usb_ep_disable() and usb_ep_enable() should only be callable from
>> process context, but that has never been a requirement before. Still,
>> it's not far-fetched to assume that a controller (such as dwc3, but
>> probably others) might sleep while cancelling a transfer because they
>> need to wait for an Interrupt.
>> 
>> In fact, we know of two controllers that need this: dwc3 and dwc3.1.
>
> It's not clear that this should be the deciding factor.  That is, does 
> usb_ep_disable() need to wait until all the endpoint's outstanding 
> transfers have been completed before it returns?  I don't think it 
> does.

not all, no. And, frankly, this is really only a problem if we're
unregistering a gadget while there are still pending transfers.

The original problem statement is that we unregister a gadget, issue End
Transfer, but CmdCompletion for the EndTransfer comes way too
late. Baolin, can you clarify again what happens when the IRQ comes
late?

>> I wonder if there are any other controllers with this
>> requirement. Either way, We should also consider if there are any strong
>> reasons to call usb_ep_disable() with interrupts disabled and locks held
>> considering that UDC _must_ call ->complete() for each and every
>> request.
>> 
>> If we go ahead with this, it'll mean a rather large series (again) to
>> fix all the calling semantics in every single gadget driver for both
>> usb_ep_enable() and usb_ep_disable(). Then, making sure all UDC drivers
>> respect the requirement, then we update documentation about the
>> functions and add might_sleep() to their implementation in udc/core.c
>> 
>> Anybody objects to this new requirement?
>
> The usual times for calling usb_ep_disable() is when the gadget driver 
> processes an altsetting or configuration change, or a reset or 
> disconnect.  The notifications for these things happen in interrupt 
> context, so it doesn't seem reasonable to require that endpoints be 
> disabled in process context.

Oh, that's true. I completely forgot about altsetting change.

> f_mass_storage has its own worker thread.  Mainly for other reasons, 
> but it can also use the thread to handle these events.  But it doesn't 
> seem right to require all gadget drivers to do the same thing.
>
> There is still an open question about how a gadget driver can change 
> altsettings, though.  A particular endpoint might be bulk in one 
> altsetting and isochronous in another, for example.  I don't see how we 
> can change the endpoint's characteristics without being allowed to 
> sleep.

Heh, seems that I ended up touching a subject that hasn't been revisited
in few years :-)

Anyway, let's see what Baolin says about the IRQ again. Now that I think
of it, free_irq() should be calling synchronize IRQ, right? So by the
time free_irq() returns, we shouldn't get any further interrupts. Also,
when the endpoint is disabled it shouldn't trigger any further
interrupts.

-- 
balbi

Attachment: signature.asc
Description: PGP signature


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

  Powered by Linux