All of lore.kernel.org
 help / color / mirror / Atom feed
From: Felipe Balbi <balbi@kernel.org>
To: Thinh Nguyen <Thinh.Nguyen@synopsys.com>,
	Thinh Nguyen <Thinh.Nguyen@synopsys.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	"linux-usb\@vger.kernel.org" <linux-usb@vger.kernel.org>
Cc: John Youn <John.Youn@synopsys.com>
Subject: Re: [PATCH] usb: dwc3: gadget: Remove incomplete check
Date: Tue, 31 Mar 2020 11:12:49 +0300	[thread overview]
Message-ID: <87tv250wou.fsf@kernel.org> (raw)
In-Reply-To: <804450e5-758c-5ec6-88ae-302c023bf1e3@synopsys.com>

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


Hi,

Thinh Nguyen <Thinh.Nguyen@synopsys.com> writes:
>> Thinh Nguyen <Thinh.Nguyen@synopsys.com> writes:
>>>>> The condition here is if (!request_complete()), then kick_transfer().
>>>>> Let's take a look at what kick_transfer() do:
>>>>>
>>>>> kick_transfer() will prepare new TRBs and issue START_TRANSFER command
>>>>> or UPDATE_TRANSFER command. The endpoint is already started, and nothing
>>>>> is causing it to end at this point. So it should just be UPDATE_TRANSFER
>>>>> command. UPDATE_TRANSFER command tells the controller to update its TRB
>>>>> cache because there will be new TRBs prepared for the request.
>>>>>
>>>>> If this is non-SG/non-chained TRB request, then there's only 1 TRB per
>>>>> request for IN endpoints. If that TRB is completed, that means that the
>>>>> request is completed. There's no reason to issue kick_transfer() again.
>>>> not entirely true for bulk. We never set LST bit; we will never complete
>>>> a transfer, we continually add more TRBs. The reason for this is to
>>>> amortize the cost of adding new transfers to the controller cache before
>>>> it runs out of TRBs without HWO.
>>> Right, I was referring to "request" rather than transfer (as in a
>>> transfer may have 1 or more requests).
>>>
>>>> How about we change the test to say "if I have non-started TRBs and I'm
>>>> bulk (non-stream) or interrupt endpoint, kick more transfers"?
>>>>
>>>>> When the function driver queues a new request, then there will be new
>>>>> TRBs to prepare and then the driver can kick_transfer() again.
>>>> We may already have more TRBs in the pending list which may not have
>>>> been started before we didn't have free TRBs to use. We just completed a
>>>> TRB, might as well try to use it for more requests.
>>> Yes we can and we should, but we didn't check that. Also it shouldn't be
>>> in the request_complete() check function as they are part of different
>>> requests.
>>>
>>>>> So, this condition to check if request_complete() is only valid for a
>>>>> request with multiple chained TRBs. Since we can only check for IN
>>>>> direction, the chained TRB setup related to OUT direction to fit
>>>>> MaxPacketSize does not apply here. What left is chained TRBs for SG. In
>>>> this part is clear now and you're correct. Thanks
>>>>
>>>>> this case, we do want to kick_transfer again. This may happen when we
>>>>> run out of TRBs and we have to wait for available TRBs. When there are
>>>>> available TRBs and still pending SGs, then we want to prepare the rest
>>>>> of the SG entries to finish the request. So kick_transfer() makes sense
>>>>> here.
>>>> Right but we can run out of TRBs even in non-chained case. I remember
>>>> testing this years ago by giving g_mass_storage a list of 300
>>>> requests. The reason for kicking the transfer is different, but it's
>>>> beneficial anyhow.
>>>>
>>> In this case, the check should be for if the pending_list is not empty,
>>> then kick again.
>>>
>>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>>> index 6a04c9afcab6..d8318de55000 100644
>>> --- a/drivers/usb/dwc3/gadget.c
>>> +++ b/drivers/usb/dwc3/gadget.c
>>> @@ -2975,14 +2975,7 @@ static int
>>> dwc3_gadget_ep_reclaim_trb_linear(struct dwc3_ep *dep,
>>>
>>>    static bool dwc3_gadget_ep_request_completed(struct dwc3_request *req)
>>>    {
>>> -       /*
>>> -        * For OUT direction, host may send less than the setup
>>> -        * length. Return true for all OUT requests.
>>> -        */
>>> -       if (!req->direction)
>>> -               return true;
>>> -
>>> -       return req->request.actual == req->request.length;
>>> +       return req->num_pending_sgs == 0;
>>>    }
>>>
>>>    static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
>>> @@ -3007,7 +3000,7 @@ static int
>>> dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
>>>           req->request.actual = req->request.length - req->remaining;
>>>
>>>           if (!dwc3_gadget_ep_request_completed(req) ||
>>> -                       req->num_pending_sgs) {
>>> +           !list_empty(&dep->pending_list)) {
>>>                   __dwc3_gadget_kick_transfer(dep);
>>>                   goto out;
>>>           }
>>>
>>>
>>> This is unlikely to happen, but it's necessary to be there.
>>>
>>> Let me know if you're ok with the change, I'll create a formal patch for it.
>> Looks good, we may just rename the function to
>> dwc3_gadget_ep_should_continue() or something similar and move the
>> !list_empty() check in there too.
>>
>
> I forgot this condition skips the dwc3_gadget_giveback(). I have to 
> split it. Let me send out the revised patches and you can review.

Sure, I think patch 1 can go in during -rc. Do we need a Cc stable on
it, though?

Patch 2 will have to wait until v5.8.

-- 
balbi

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

  reply	other threads:[~2020-03-31  8:12 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-06  3:44 [PATCH] usb: dwc3: gadget: Remove incomplete check Thinh Nguyen
2020-03-15  9:19 ` Felipe Balbi
2020-03-16  0:33   ` Thinh Nguyen
2020-03-16  7:00     ` Felipe Balbi
2020-03-16 20:37       ` Thinh Nguyen
2020-03-29  8:03         ` Felipe Balbi
2020-03-29 23:44           ` Thinh Nguyen
2020-03-30  8:26             ` Felipe Balbi
2020-03-30 19:30               ` Thinh Nguyen
2020-03-30 21:34                 ` Felipe Balbi
2020-03-31  1:47                   ` Thinh Nguyen
2020-03-31  8:12                     ` Felipe Balbi [this message]
2020-03-31  8:39                       ` Thinh Nguyen

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=87tv250wou.fsf@kernel.org \
    --to=balbi@kernel.org \
    --cc=John.Youn@synopsys.com \
    --cc=Thinh.Nguyen@synopsys.com \
    --cc=gregkh@linuxfoundation.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.