From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
To: Selvarasu Ganesan <selvarasu.g@samsung.com>
Cc: Thinh Nguyen <Thinh.Nguyen@synopsys.com>,
Alan Stern <stern@rowland.harvard.edu>,
"gregkh@linuxfoundation.org" <gregkh@linuxfoundation.org>,
"linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"jh0801.jung@samsung.com" <jh0801.jung@samsung.com>,
"dh10.jung@samsung.com" <dh10.jung@samsung.com>,
"naushad@samsung.com" <naushad@samsung.com>,
"akash.m5@samsung.com" <akash.m5@samsung.com>,
"h10.kim@samsung.com" <h10.kim@samsung.com>,
"eomji.oh@samsung.com" <eomji.oh@samsung.com>,
"alim.akhtar@samsung.com" <alim.akhtar@samsung.com>,
"thiagu.r@samsung.com" <thiagu.r@samsung.com>,
"stable@vger.kernel.org" <stable@vger.kernel.org>
Subject: Re: [PATCH v2] usb: dwc3: gadget: Prevent EPs resource conflict during StartTransfer
Date: Fri, 12 Dec 2025 01:21:11 +0000 [thread overview]
Message-ID: <20251212012108.wjn2pavyg6qaiytt@synopsys.com> (raw)
In-Reply-To: <28035b59-3138-40e6-beb3-1a3793e8df84@samsung.com>
On Thu, Dec 11, 2025, Selvarasu Ganesan wrote:
>
> On 12/5/2025 6:48 AM, Thinh Nguyen wrote:
> >> I was hoping that the dwc3_gadget_ep_queue() won't come early to run
> >> into this scenario. What I've provided will only mitigate and will not
> >> resolve for all cases. It seems adding more checks in dwc3 will be
> >> more messy.
>
>
> Hi Thinh,
>
>
> Thank you for the insightful comments. I agree that adding more checks
> directly in the dwc3 driver would be messy, and a comprehensive rework
> of the dwc3 ep disable would ultimately be the cleaner solution.
>
> In the meantime, Introducing additional checks for
> DWC3_EP_TRANSFER_STARTED in dwc3 driver is the most practical way to
> unblock the current issue while we work toward that longer‑term fix.
> We have applied the patches and performed additional testing, no
> regressions or new issues were observed.
>
> Could you please confirm whether below interim fix is acceptable along
> with your proposed earlier patch for unblocking the current development
> flow?
>
>
> Patch 2: usb: dwc3: protect dep->flags from concurrent modify in
> dwc3_gadget_ep_disable
> =======================================================================================
>
> Subject: [PATCH] usb: dwc3: protect dep->flags from concurrent modify in
> dwc3_gadget_ep_disable
> The below warnings in `dwc3_gadget_ep_queue` observed during the RNDIS
> enable/disable test is caused by a race between `dwc3_gadget_ep_disable`
> and `dwc3_gadget_ep_queue`. Both functions manipulate `dep->flags`, and
> the lock released temporarily by `dwc3_gadget_giveback` (called from
> `dwc3_gadget_ep_disable`) can be acquired by `dwc3_gadget_ep_queue`
> before `dwc3_gadget_ep_disable` has finished. This leads to an
> inconsistent state of the `DWC3_EP_TRANSFER_STARTED` dep->flag.
>
> To fix this issue by add a condition check when masking `dep->flags`
> in `dwc3_gadget_ep_disable` to ensure the `DWC3_EP_TRANSFER_STARTED`
> flag is not cleared when it is actually set. This prevents the spurious
> warning and eliminates the race.
>
> Thread#1:
> dwc3_gadget_ep_disable
> ->__dwc3_gadget_ep_disable
> ->dwc3_remove_requests
> ->dwc3_stop_active_transfer
> ->__dwc3_stop_active_transfer
> -> dwc3_send_gadget_ep_cmd (cmd =DWC3_DEPCMD_ENDTRANSFER)
> ->if(!interrupt)dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
> ->dwc3_gadget_giveback
> ->spin_unlock(&dwc->lock)
> ...
> While Thread#1 is still running, Thread#2 starts:
>
> Thread#2:
> usb_ep_queue
> ->dwc3_gadget_ep_queue
> ->__dwc3_gadget_kick_transfer
> -> starting = !(dep->flags & DWC3_EP_TRANSFER_STARTED);
> ->if(starting)
> ->dwc3_send_gadget_ep_cmd (cmd = DWC3_DEPCMD_STARTTRANSFER)
> ->dep->flags |= DWC3_EP_TRANSFER_STARTED;
> ...
> ->__dwc3_gadget_ep_disable
> ->mask = DWC3_EP_TXFIFO_RESIZED |DWC3_EP_RESOURCE_ALLOCATED;
> ->dep->flags &= mask; --> // Possible of clears
> DWC3_EP_TRANSFER_STARTED flag as well without
> sending DWC3_DEPCMD_ENDTRANSFER
>
> ------------[ cut here ]------------
> dwc3 13200000.dwc3: No resource for ep1in
> WARNING: CPU: 7 PID: 1748 at drivers/usb/dwc3/gadget.c:398
> dwc3_send_gadget_ep_cmd+0x2f8/0x76c
> pc : dwc3_send_gadget_ep_cmd+0x2f8/0x76c
> lr : dwc3_send_gadget_ep_cmd+0x2f8/0x76c
> Call trace:
> dwc3_send_gadget_ep_cmd+0x2f8/0x76c
> __dwc3_gadget_kick_transfer+0x2ec/0x3f4
> dwc3_gadget_ep_queue+0x140/0x1f0
> usb_ep_queue+0x60/0xec
> mp_tx_task+0x100/0x134
> mp_tx_timeout+0xd0/0x1e0
> __hrtimer_run_queues+0x130/0x318
> hrtimer_interrupt+0xe8/0x340
> exynos_mct_comp_isr+0x58/0x80
> __handle_irq_event_percpu+0xcc/0x25c
> handle_irq_event+0x40/0x9c
> handle_fasteoi_irq+0x154/0x2c8
> generic_handle_domain_irq+0x58/0x80
> gic_handle_irq+0x48/0x104
> call_on_irq_stack+0x3c/0x50
> do_interrupt_handler+0x4c/0x84
> el1_interrupt+0x34/0x58
> el1h_64_irq_handler+0x18/0x24
> el1h_64_irq+0x68/0x6c
>
> Change-Id: Ib6a77ce5130e25d0162f72d0e52c845dbb1d18f5
> Signed-off-by: Selvarasu Ganesan <selvarasu.g@samsung.com>
> ---
> drivers/usb/dwc3/gadget.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index b42d225b67408..1dc5798072120 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -1051,6 +1051,22 @@ static int __dwc3_gadget_ep_disable(struct
> dwc3_ep *dep)
> */
> if (dep->flags & DWC3_EP_DELAY_STOP)
> mask |= (DWC3_EP_DELAY_STOP | DWC3_EP_TRANSFER_STARTED);
> +
> + /*
> + * When dwc3_gadget_ep_disable() calls dwc3_gadget_giveback(),
> + * the dwc->lock is temporarily released. If dwc3_gadget_ep_queue()
> + * runs in that window it may set the DWC3_EP_TRANSFER_STARTED flag as
> + * part of dwc3_send_gadget_ep_cmd. The original code cleared the flag
> + * unconditionally, which could overwrite the concurrent modification.
> + *
> + * The added check ensures the DWC3_EP_TRANSFER_STARTED flag is only
> + * cleared if it is not set already, preserving the state updated
> by the
> + * concurrent ep_queue path and eliminating the EP resource conflict
> + * warning.
> + */
We need to explain the underlining problem here and in the commit
message. The function usb_ep_disable() is expected be used interrupt
context, and it's being used in interrupt context in the composite
framework. There's no wait for flushing of endpoint is handled before
usb_ep_disable completes.
We are adding a temporary workaround to handle the endpoint
reconfiguration and restart before the flushing completed.
> + if (dep->flags & DWC3_EP_TRANSFER_STARTED)
> + mask |= DWC3_EP_TRANSFER_STARTED;
> +
> dep->flags &= mask;
>
> /* Clear out the ep descriptors for non-ep0 */
> --
>
> 2.31.1
>
>
For your case, it may work because the endpoint is probably reconfigured
to be the same in usb_ep_enable(). If we reconfigure the endpoint before
the endpoint is stopped, the behavior is underfined.
You can create the patches and Cc stable. However, I would not add the
"Fixes" tag since they (IMHO) are not really fixes. May also need to
note that under the "---" in the commit explain why there's no Fixes tag
also.
Thanks,
Thinh
next prev parent reply other threads:[~2025-12-12 1:59 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20251117160057epcas5p324eddf1866146216495186a50bcd3c01@epcas5p3.samsung.com>
2025-11-17 15:59 ` [PATCH v2] usb: dwc3: gadget: Prevent EPs resource conflict during StartTransfer Selvarasu Ganesan
2025-11-18 2:21 ` Thinh Nguyen
2025-11-18 3:58 ` Selvarasu Ganesan
2025-11-19 1:56 ` Thinh Nguyen
2025-11-18 4:20 ` Alan Stern
2025-11-19 1:49 ` Thinh Nguyen
2025-11-19 4:09 ` Alan Stern
2025-11-20 2:07 ` Thinh Nguyen
2025-11-20 3:33 ` Alan Stern
2025-11-21 2:22 ` Thinh Nguyen
2025-11-21 3:08 ` Alan Stern
2025-12-03 5:25 ` Selvarasu Ganesan
2025-12-04 1:51 ` Thinh Nguyen
2025-12-04 13:15 ` Selvarasu Ganesan
2025-12-05 0:37 ` Thinh Nguyen
2025-12-05 1:18 ` Thinh Nguyen
2025-12-05 1:19 ` Thinh Nguyen
2025-12-11 10:38 ` Selvarasu Ganesan
2025-12-12 1:21 ` Thinh Nguyen [this message]
2026-02-26 10:59 ` Selvarasu Ganesan
2026-02-26 18:41 ` Thinh Nguyen
2026-03-02 5:56 ` Selvarasu Ganesan
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=20251212012108.wjn2pavyg6qaiytt@synopsys.com \
--to=thinh.nguyen@synopsys.com \
--cc=akash.m5@samsung.com \
--cc=alim.akhtar@samsung.com \
--cc=dh10.jung@samsung.com \
--cc=eomji.oh@samsung.com \
--cc=gregkh@linuxfoundation.org \
--cc=h10.kim@samsung.com \
--cc=jh0801.jung@samsung.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=naushad@samsung.com \
--cc=selvarasu.g@samsung.com \
--cc=stable@vger.kernel.org \
--cc=stern@rowland.harvard.edu \
--cc=thiagu.r@samsung.com \
/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