From: sashiko-bot@kernel.org
To: "Thinh Nguyen" <Thinh.Nguyen@synopsys.com>
Cc: "linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>
Subject: Re: [PATCH 3/7] usb: dwc3: gadget: Clear delayed stop on End Transfer completion
Date: Wed, 21 Oct 2026 00:58:16 +0000 [thread overview]
Message-ID: <sashiko-outbox-179651@kernel.org> (raw)
In-Reply-To: <c28a9660f7b6bfa626077ddcfbadd50e6b503f86.1792542945.git.Thinh.Nguyen@synopsys.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] usb: dwc3: gadget: skipped request cleanup on DWC3_EP_DELAY_STOP clear
--
commit f4ade355ebc7b629210edc8108aa9f5fb3f0bcc2
Author: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
usb: dwc3: gadget: Clear delayed stop on End Transfer completion
This commit clears the DWC3_EP_DELAY_STOP flag in
dwc3_gadget_endpoint_command_complete() when an End Transfer command
completes, preventing a later retry on the next SETUP phase from stopping a
newly started transfer.
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index df5407e757884..4de3b81cb6781 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -3875,6 +3875,7 @@ static void dwc3_gadget_endpoint_command_complete(struct dwc3_ep *dep,
> if (dep->stream_capable)
> dep->flags |= DWC3_EP_IGNORE_NEXT_NOSTREAM;
>
> + dep->flags &= ~DWC3_EP_DELAY_STOP;
> dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
> dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
> dwc3_gadget_ep_cleanup_cancelled_requests(dep);
[Severity: High]
Can clearing DWC3_EP_DELAY_STOP unconditionally here in
dwc3_gadget_endpoint_command_complete() in drivers/usb/dwc3/gadget.c skip
deferred request cleanup and leak usb_request objects (and their mapped DMA
buffers) if the endpoint was disabled or the controller disconnected while
DWC3_EP_DELAY_STOP was set?
In __dwc3_stop_active_transfer(), if dwc3_send_gadget_ep_cmd() with
DWC3_DEPCMD_CMDIOC returns -ETIMEDOUT while dep->dwc->ep0state !=
EP0_SETUP_PHASE (for example, while dwc->delayed_status is true in
dwc3_gadget_ep_dequeue(), __dwc3_gadget_ep_set_halt(),
__dwc3_gadget_kick_transfer(), or __dwc3_gadget_ep_disable() after commit
"usb: dwc3: gadget: Wait for End Transfer completion on ep disable", or via
__dwc3_gadget_start_isoc()), the driver sets DWC3_EP_DELAY_STOP and returns
0 without clearing DWC3_EP_TRANSFER_STARTED (and before scheduling error
recovery in commit "usb: dwc3: gadget: Recover from End Transfer timeout"),
while the End Transfer command remains in flight in hardware.
If __dwc3_gadget_ep_disable() or dwc3_gadget_soft_disconnect() then runs
before EP0 reaches EP0_SETUP_PHASE, dwc3_remove_requests() returns early
without giving back dep->started_list, dep->pending_list, or
dep->cancelled_list:
drivers/usb/dwc3/gadget.c:dwc3_remove_requests() {
...
dwc3_stop_active_transfer(dep, false, false);
/* If endxfer is delayed, avoid unmapping requests */
if (dep->flags & DWC3_EP_DELAY_STOP)
return;
...
}
And in __dwc3_gadget_ep_disable(), dep->endpoint.desc is cleared while
DWC3_EP_DELAY_STOP | DWC3_EP_TRANSFER_STARTED remain set:
drivers/usb/dwc3/gadget.c:__dwc3_gadget_ep_disable() {
...
if (dep->flags & DWC3_EP_DELAY_STOP)
mask |= (DWC3_EP_DELAY_STOP | DWC3_EP_TRANSFER_STARTED);
dep->flags &= mask;
/* Clear out the ep descriptors for non-ep0 */
if (dep->number > 1) {
dep->endpoint.comp_desc = NULL;
dep->endpoint.desc = NULL;
}
...
}
If the in-flight End Transfer command completes before dwc3_ep0_out_start()
runs, dwc3_gadget_endpoint_command_complete() now clears DWC3_EP_DELAY_STOP
and only calls dwc3_gadget_ep_cleanup_cancelled_requests(dep), which does
not clean up dep->started_list or dep->pending_list, and stops after the
first request in dep->cancelled_list when the endpoint is disabled:
drivers/usb/dwc3/gadget.c:dwc3_gadget_ep_cleanup_cancelled_requests() {
...
/*
* The endpoint is disabled, let the dwc3_remove_requests()
* handle the cleanup.
*/
if (!dep->endpoint.desc)
break;
}
}
Because DWC3_EP_DELAY_STOP has already been cleared, when
dwc3_ep0_out_start() later runs on entering EP0_SETUP_PHASE, it will skip
the endpoint instead of finishing the deferred dwc3_remove_requests()
cleanup:
drivers/usb/dwc3/ep0.c:dwc3_ep0_out_start() {
...
if (!(dwc3_ep->flags & DWC3_EP_DELAY_STOP))
continue;
dwc3_ep->flags &= ~DWC3_EP_DELAY_STOP;
if (dwc->connected)
dwc3_stop_active_transfer(dwc3_ep, false, true);
else
dwc3_remove_requests(dwc, dwc3_ep, -ESHUTDOWN);
...
}
Additionally, in the dwc3_gadget_soft_disconnect() path where
!dwc->connected (while ep0state is still EP0_STATUS_PHASE after
dwc3_ep0_send_delayed_status() clears dwc->delayed_status),
dep->endpoint.desc is still non-NULL and DWC3_EP_ENABLED is still set. If
DWC3_EP_DELAY_START was set prior to disconnect, could
dwc3_gadget_endpoint_command_complete() also call
__dwc3_gadget_kick_transfer(dep) and start a new hardware transfer from
dep->pending_list while disconnecting?
Should dwc3_gadget_endpoint_command_complete() check whether the endpoint
was disabled (!dep->endpoint.desc) or disconnected (!dwc->connected) when
DWC3_EP_DELAY_STOP was set and invoke dwc3_remove_requests(dwc, dep,
-ESHUTDOWN) instead of kicking delayed transfers?
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1792542945.git.Thinh.Nguyen@synopsys.com?part=3
next prev parent reply other threads:[~2026-10-21 0:58 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 0:37 [PATCH 0/7] usb: dwc3: gadget: Fix No Resource after End Transfer Thinh Nguyen
2026-10-21 0:37 ` [PATCH 1/7] usb: dwc3: gadget: Reject requests to a disabled endpoint Thinh Nguyen
2026-10-21 0:44 ` sashiko-bot
2026-10-21 0:37 ` [PATCH 2/7] usb: dwc3: gadget: Track a timed out End Transfer Thinh Nguyen
2026-10-21 0:43 ` sashiko-bot
2026-10-21 0:38 ` [PATCH 3/7] usb: dwc3: gadget: Clear delayed stop on End Transfer completion Thinh Nguyen
2026-10-21 0:58 ` sashiko-bot [this message]
2026-10-21 0:38 ` [PATCH 4/7] usb: dwc3: gadget: Issue no-op Start Transfer only for stream endpoints Thinh Nguyen
2026-10-21 0:48 ` sashiko-bot
2026-10-21 0:38 ` [PATCH 5/7] usb: dwc3: gadget: Wait for End Transfer completion on ep disable Thinh Nguyen
2026-10-21 1:13 ` sashiko-bot
2026-10-21 0:38 ` [PATCH 6/7] usb: dwc3: gadget: Reset endpoint flags on controller start Thinh Nguyen
2026-10-21 1:03 ` sashiko-bot
2026-10-21 0:38 ` [PATCH 7/7] usb: dwc3: gadget: Recover from End Transfer timeout Thinh Nguyen
2026-10-21 1:05 ` sashiko-bot
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=sashiko-outbox-179651@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Thinh.Nguyen@synopsys.com \
--cc=linux-usb@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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.