linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Felipe Balbi <balbi@kernel.org>
To: Baolin Wang <baolin.wang@linaro.org>
Cc: Greg KH <gregkh@linuxfoundation.org>,
	USB <linux-usb@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Linaro Kernel Mailman List <linaro-kernel@lists.linaro.org>,
	Mark Brown <broonie@kernel.org>
Subject: Re: [PATCH] usb: dwc3: ep0: Fix the possible missed request for handling delay STATUS phase
Date: Mon, 16 Jan 2017 13:29:45 +0200	[thread overview]
Message-ID: <878tqbmedy.fsf@linux.intel.com> (raw)
In-Reply-To: <CAMz4kuJtrF8d+pNiynqVZn=XHEJQq0pVvTRQWi5m4+grdK4m4Q@mail.gmail.com>

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


Hi,

Baolin Wang <baolin.wang@linaro.org> writes:
> Hi,
>
> On 16 January 2017 at 18:56, Felipe Balbi <balbi@kernel.org> wrote:
>>
>> Hi,
>>
>> Baolin Wang <baolin.wang@linaro.org> writes:
>>> When handing the SETUP packet by composite_setup(), we will release the
>>> dwc->lock. If we get the 'USB_GADGET_DELAYED_STATUS' result from setup
>>> function, which means we need to delay handling the STATUS phase.
>>
>> this sentence needs a little work. Seems like it's missing some
>> information.
>>
>> anyway, I get that we release the lock but...
>>
>>> But during the lock release period, maybe the request for handling delay
>>
>> execution of ->setup() itself should be locked. I can see that it's only
>> locked for set_config() which is rather peculiar.
>>
>> What exact request you had when you triggered this? (Hint: dwc3
>> tracepoints print out ctrl request bytes). IIRC, only set_config() or
>> f->set_alt() can actually return USB_GADGET_DELAYED_STATUS.
>
> Yes, when host set configuration for mass storage driver, it can
> produce this issue.
>
>>
>> Which gadget driver were you using when you triggered this?
>
> mass storage driver. When host issues the setting config request, we
> will get USB_GADGET_DELAYED_STATUS result from
> set_config()--->fsg_set_alt(). Then the mass storage driver will issue
> one thread to complete the status stage by ep0_queue() (this thread
> may be running on another core), then if the thread issues ep0_queue()
> too fast before we get the dwc->lock in dwc3_ep0_delegate_req() or
> before we get into the STATUS stage, then we can not handle this
> request for the delay STATUS stage in dwc3_gadget_ep0_queue().
>
>>
>> Another point here is that the really robust way of fixing this is to
>> get rid of USB_GADGET_DELAYED_STATUS altogether and just make sure
>> gadget drivers know how to queue requests for all three phases of a
>> Control Transfer.
>>
>> A lot of code will be removed from all gadget drivers and UDC drivers
>> while combining all of it in a single place in composite.c.
>>
>> The reason I'm saying this is that other UDC drivers might have similar
>> races already but they just haven't triggered.
>
> Yes, maybe.
>
>>
>>> STATUS phase has been queued into list before we set 'dwc->delayed_status'
>>> flag or entering 'EP0_STATUS_PHASE' phase, then we will miss the chance
>>> to handle the STATUS phase. Thus we should check if the request for delay
>>> STATUS phase has been enqueued when entering 'EP0_STATUS_PHASE' phase in
>>> dwc3_ep0_xfernotready(), if so, we should handle it.
>>>
>>> Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
>>> ---
>>>  drivers/usb/dwc3/ep0.c |   14 ++++++++++++++
>>>  1 file changed, 14 insertions(+)
>>>
>>> diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
>>> index 9bb1f85..e689ced 100644
>>> --- a/drivers/usb/dwc3/ep0.c
>>> +++ b/drivers/usb/dwc3/ep0.c
>>> @@ -1123,7 +1123,21 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
>>>               dwc->ep0state = EP0_STATUS_PHASE;
>>>
>>>               if (dwc->delayed_status) {
>>> +                     struct dwc3_ep *dep = dwc->eps[0];
>>> +
>>>                       WARN_ON_ONCE(event->endpoint_number != 1);
>>> +                     /*
>>> +                      * We should handle the delay STATUS phase here if the
>>> +                      * request for handling delay STATUS has been queued
>>> +                      * into the list.
>>> +                      */
>>> +                     if (!list_empty(&dep->pending_list)) {
>>> +                             dwc->delayed_status = false;
>>> +                             usb_gadget_set_state(&dwc->gadget,
>>> +                                                  USB_STATE_CONFIGURED);
>>
>> Isn't this patch also changing the normal case when usb_ep_queue() comes
>> later? I guess list_empty() protects against that...
>
> I think it will not change other cases, we only handle the delayed
> status and I've tested it for a while and I did not find any problem.

Alright, it's important enough to fix this bug. Can you also have a look
into dropping USB_GADGET_DELAYED_STATUS altogether? If you're too busy,
no issues. It'll stay in my queue.

-- 
balbi

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

  reply	other threads:[~2017-01-16 11:31 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-14  8:40 [PATCH] usb: dwc3: ep0: Fix the possible missed request for handling delay STATUS phase Baolin Wang
2017-01-16 10:56 ` Felipe Balbi
2017-01-16 11:29   ` Baolin Wang
2017-01-16 11:29     ` Felipe Balbi [this message]
2017-01-16 12:00       ` Baolin Wang
2017-01-16 12:06         ` Felipe Balbi
2017-01-16 17:53           ` Alan Stern
2017-01-16 19:18             ` Felipe Balbi
2017-01-17 15:54               ` Alan Stern
2017-01-23 11:57                 ` Felipe Balbi
2017-02-17  5:41                   ` Baolin Wang
2017-02-17  8:04                     ` Felipe Balbi
2017-02-20  2:27                       ` Baolin Wang
2017-02-21  9:18                       ` Baolin Wang
2017-02-27 22:11                         ` Alan Stern
2017-02-28 11:56                           ` Felipe Balbi
2017-02-28 18:34                             ` Alan Stern
2017-03-02 10:43                               ` Felipe Balbi
2017-03-02 10:15                           ` Baolin Wang
2017-03-02 10:48                             ` Felipe Balbi
2017-01-17  7:02           ` Baolin Wang
2017-01-17 10:39             ` Felipe Balbi
2017-01-17 11:40               ` Baolin Wang

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=878tqbmedy.fsf@linux.intel.com \
    --to=balbi@kernel.org \
    --cc=baolin.wang@linaro.org \
    --cc=broonie@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=linaro-kernel@lists.linaro.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).