* [PATCH RESEND] usb: dwc3: gadget: don't error on dequeue of a completed request
@ 2026-09-04 16:13 Cole Munz
2026-09-04 16:16 ` Greg Kroah-Hartman
0 siblings, 1 reply; 9+ messages in thread
From: Cole Munz @ 2026-09-04 16:13 UTC (permalink / raw)
To: Thinh Nguyen, Greg Kroah-Hartman; +Cc: linux-usb, linux-kernel
Dequeuing a request that has already been given back logs an error and
returns -EINVAL:
dwc3 23000000.usb: request 00000000ad92f1c4 was not queued to ep0out
f_fs hits this on every teardown. functionfs_unbind() dequeues ep0req
unconditionally before freeing it, which
commit ce405d561b02 ("usb: gadget: f_fs: Ensure ep0req is dequeued
before free_request") made deliberate to close a use-after-free. By then
the control transfer has long completed, so dwc3_gadget_ep_dequeue()
finds the request on none of cancelled_list, pending_list or
started_list and falls through to the error path.
Nothing is actually wrong. The request is not queued, which is what the
caller asked for, and both callers ignore the return value and free the
request straight after. The only effect is an error line in every gadget
teardown, which buries real USB errors.
dwc3 already tracks enough to tell the two cases apart.
dwc3_gadget_ep_alloc_request() sets DWC3_REQUEST_STATUS_UNKNOWN, both
__dwc3_gadget_ep_queue() and __dwc3_gadget_ep0_queue() set
DWC3_REQUEST_STATUS_QUEUED, and dwc3_gadget_giveback() sets
DWC3_REQUEST_STATUS_COMPLETED. A request that reaches the end of dequeue
with status COMPLETED was queued to this endpoint and has finished.
Anything else was never queued here, or the driver lost track of it.
Keep the error for those, and return success for a completed request.
A completed request still has to be dequeued on the endpoint it belongs
to. req->dep is set once at allocation and never changes, and
__dwc3_gadget_ep_queue() rejects the same mismatch with a WARN, so a
wrong-endpoint dequeue stays on the error path here as well.
This is narrower than the cdnsp fix for the same caller,
commit 34f08eb0ba6e ("usb: cdnsp: Fixes issue with dequeuing not queued
requests"), which returns 0 whenever usb_request::status is not
-EINPROGRESS. That also swallows a request that was never queued, since
status is zero out of allocation. Going by dwc3's own request status
keeps that case an error, which is what was asked for when a separate
ep0 dequeue was proposed in 2022.
Link: https://lore.kernel.org/linux-usb/20221117054917.30104-1-quic_ugoswami@quicinc.com/
Signed-off-by: Cole Munz <Munzzyy1@proton.me>
---
Resend, no changes to the patch. The original went out on 17 August, the day
after v7.2, so it arrived at the top of the merge window.
Rebased onto v7.3-rc1 and rechecked there: applies clean, gadget.o builds
under W=1 with no new warnings, sparse and checkpatch --strict are clean.
The Flipper Zero kernel tree ran into this on their gadget teardown path and
merged the same patch downstream today, so it is in use if that helps place it.
Original posting:
https://lore.kernel.org/linux-usb/18ebf019a119389870bbc7c155a00a86bf867323.1786985009.git.Munzzyy1@proton.me/
drivers/usb/dwc3/gadget.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index fa944856f956..f68eb9254afa 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2181,9 +2181,22 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
}
}
- dev_err(dwc->dev, "request %p was not queued to %s\n",
- request, ep->name);
- ret = -EINVAL;
+ /*
+ * The request is on none of this endpoint's lists. That is the
+ * expected state once it has been given back: a function may dequeue
+ * a request before freeing it, and f_fs does so unconditionally for
+ * ep0req in functionfs_unbind(). Nothing is queued, which is what the
+ * caller asked for, so report success. Any other status means the
+ * request was never queued here or the driver lost track of it, and
+ * stays an error. So does a completed request handed to the wrong
+ * endpoint: req->dep is fixed at allocation, and the queue side
+ * rejects the same mismatch.
+ */
+ if (req->status != DWC3_REQUEST_STATUS_COMPLETED || req->dep != dep) {
+ dev_err(dwc->dev, "request %p was not queued to %s\n",
+ request, ep->name);
+ ret = -EINVAL;
+ }
out:
spin_unlock_irqrestore(&dwc->lock, flags);
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
--
2.55.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH RESEND] usb: dwc3: gadget: don't error on dequeue of a completed request
2026-09-04 16:13 [PATCH RESEND] usb: dwc3: gadget: don't error on dequeue of a completed request Cole Munz
@ 2026-09-04 16:16 ` Greg Kroah-Hartman
2026-09-04 16:58 ` [PATCH v2] " Cole Munz
0 siblings, 1 reply; 9+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-04 16:16 UTC (permalink / raw)
To: Cole Munz; +Cc: Thinh Nguyen, linux-usb, linux-kernel
On Fri, Sep 04, 2026 at 04:13:55PM +0000, Cole Munz wrote:
> Dequeuing a request that has already been given back logs an error and
> returns -EINVAL:
>
> dwc3 23000000.usb: request 00000000ad92f1c4 was not queued to ep0out
>
> f_fs hits this on every teardown. functionfs_unbind() dequeues ep0req
> unconditionally before freeing it, which
> commit ce405d561b02 ("usb: gadget: f_fs: Ensure ep0req is dequeued
> before free_request") made deliberate to close a use-after-free. By then
> the control transfer has long completed, so dwc3_gadget_ep_dequeue()
> finds the request on none of cancelled_list, pending_list or
> started_list and falls through to the error path.
>
> Nothing is actually wrong. The request is not queued, which is what the
> caller asked for, and both callers ignore the return value and free the
> request straight after. The only effect is an error line in every gadget
> teardown, which buries real USB errors.
>
> dwc3 already tracks enough to tell the two cases apart.
> dwc3_gadget_ep_alloc_request() sets DWC3_REQUEST_STATUS_UNKNOWN, both
> __dwc3_gadget_ep_queue() and __dwc3_gadget_ep0_queue() set
> DWC3_REQUEST_STATUS_QUEUED, and dwc3_gadget_giveback() sets
> DWC3_REQUEST_STATUS_COMPLETED. A request that reaches the end of dequeue
> with status COMPLETED was queued to this endpoint and has finished.
> Anything else was never queued here, or the driver lost track of it.
> Keep the error for those, and return success for a completed request.
>
> A completed request still has to be dequeued on the endpoint it belongs
> to. req->dep is set once at allocation and never changes, and
> __dwc3_gadget_ep_queue() rejects the same mismatch with a WARN, so a
> wrong-endpoint dequeue stays on the error path here as well.
>
> This is narrower than the cdnsp fix for the same caller,
> commit 34f08eb0ba6e ("usb: cdnsp: Fixes issue with dequeuing not queued
> requests"), which returns 0 whenever usb_request::status is not
> -EINPROGRESS. That also swallows a request that was never queued, since
> status is zero out of allocation. Going by dwc3's own request status
> keeps that case an error, which is what was asked for when a separate
> ep0 dequeue was proposed in 2022.
>
> Link: https://lore.kernel.org/linux-usb/20221117054917.30104-1-quic_ugoswami@quicinc.com/
> Signed-off-by: Cole Munz <Munzzyy1@proton.me>
Did you forget an Assisted-by: tag?
A cc: stable?
A Fixes: tag?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2] usb: dwc3: gadget: don't error on dequeue of a completed request
2026-09-04 16:16 ` Greg Kroah-Hartman
@ 2026-09-04 16:58 ` Cole Munz
2026-09-04 17:07 ` Greg Kroah-Hartman
0 siblings, 1 reply; 9+ messages in thread
From: Cole Munz @ 2026-09-04 16:58 UTC (permalink / raw)
To: Thinh Nguyen, Greg Kroah-Hartman; +Cc: linux-usb, linux-kernel, stable
Dequeuing a request that has already been given back logs an error and
returns -EINVAL:
dwc3 23000000.usb: request 00000000ad92f1c4 was not queued to ep0out
f_fs hits this on every teardown. functionfs_unbind() dequeues ep0req
unconditionally before freeing it, which
commit ce405d561b02 ("usb: gadget: f_fs: Ensure ep0req is dequeued
before free_request") made deliberate to close a use-after-free. By then
the control transfer has long completed, so dwc3_gadget_ep_dequeue()
finds the request on none of cancelled_list, pending_list or
started_list and falls through to the error path.
Nothing is actually wrong. The request is not queued, which is what the
caller asked for, and both callers ignore the return value and free the
request straight after. The only effect is an error line in every gadget
teardown, which buries real USB errors.
dwc3 already tracks enough to tell the two cases apart.
dwc3_gadget_ep_alloc_request() sets DWC3_REQUEST_STATUS_UNKNOWN, both
__dwc3_gadget_ep_queue() and __dwc3_gadget_ep0_queue() set
DWC3_REQUEST_STATUS_QUEUED, and dwc3_gadget_giveback() sets
DWC3_REQUEST_STATUS_COMPLETED. A request that reaches the end of dequeue
with status COMPLETED was queued to this endpoint and has finished.
Anything else was never queued here, or the driver lost track of it.
Keep the error for those, and return success for a completed request.
A completed request still has to be dequeued on the endpoint it belongs
to. req->dep is set once at allocation and never changes, and
__dwc3_gadget_ep_queue() rejects the same mismatch with a WARN, so a
wrong-endpoint dequeue stays on the error path here as well.
This is narrower than the cdnsp fix for the same caller,
commit 34f08eb0ba6e ("usb: cdnsp: Fixes issue with dequeuing not queued
requests"), which returns 0 whenever usb_request::status is not
-EINPROGRESS. That also swallows a request that was never queued, since
status is zero out of allocation. Going by dwc3's own request status
keeps that case an error, which is what was asked for when a separate
ep0 dequeue was proposed in 2022.
Fixes: 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/linux-usb/20221117054917.30104-1-quic_ugoswami@quicinc.com/
Assisted-by: LLM sparse
Signed-off-by: Cole Munz <Munzzyy1@proton.me>
---
All three were missing, sorry about that.
v2: add Fixes:, Cc: stable and Assisted-by tags. No code change.
drivers/usb/dwc3/gadget.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index fa944856f956..f68eb9254afa 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2181,9 +2181,22 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
}
}
- dev_err(dwc->dev, "request %p was not queued to %s\n",
- request, ep->name);
- ret = -EINVAL;
+ /*
+ * The request is on none of this endpoint's lists. That is the
+ * expected state once it has been given back: a function may dequeue
+ * a request before freeing it, and f_fs does so unconditionally for
+ * ep0req in functionfs_unbind(). Nothing is queued, which is what the
+ * caller asked for, so report success. Any other status means the
+ * request was never queued here or the driver lost track of it, and
+ * stays an error. So does a completed request handed to the wrong
+ * endpoint: req->dep is fixed at allocation, and the queue side
+ * rejects the same mismatch.
+ */
+ if (req->status != DWC3_REQUEST_STATUS_COMPLETED || req->dep != dep) {
+ dev_err(dwc->dev, "request %p was not queued to %s\n",
+ request, ep->name);
+ ret = -EINVAL;
+ }
out:
spin_unlock_irqrestore(&dwc->lock, flags);
--
2.55.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2] usb: dwc3: gadget: don't error on dequeue of a completed request
2026-09-04 16:58 ` [PATCH v2] " Cole Munz
@ 2026-09-04 17:07 ` Greg Kroah-Hartman
2026-09-04 20:00 ` [PATCH v3] " Cole Munz
0 siblings, 1 reply; 9+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-04 17:07 UTC (permalink / raw)
To: Cole Munz; +Cc: Thinh Nguyen, linux-usb, linux-kernel, stable
On Fri, Sep 04, 2026 at 04:58:57PM +0000, Cole Munz wrote:
> Dequeuing a request that has already been given back logs an error and
> returns -EINVAL:
>
> dwc3 23000000.usb: request 00000000ad92f1c4 was not queued to ep0out
>
> f_fs hits this on every teardown. functionfs_unbind() dequeues ep0req
> unconditionally before freeing it, which
> commit ce405d561b02 ("usb: gadget: f_fs: Ensure ep0req is dequeued
> before free_request") made deliberate to close a use-after-free. By then
> the control transfer has long completed, so dwc3_gadget_ep_dequeue()
> finds the request on none of cancelled_list, pending_list or
> started_list and falls through to the error path.
>
> Nothing is actually wrong. The request is not queued, which is what the
> caller asked for, and both callers ignore the return value and free the
> request straight after. The only effect is an error line in every gadget
> teardown, which buries real USB errors.
>
> dwc3 already tracks enough to tell the two cases apart.
> dwc3_gadget_ep_alloc_request() sets DWC3_REQUEST_STATUS_UNKNOWN, both
> __dwc3_gadget_ep_queue() and __dwc3_gadget_ep0_queue() set
> DWC3_REQUEST_STATUS_QUEUED, and dwc3_gadget_giveback() sets
> DWC3_REQUEST_STATUS_COMPLETED. A request that reaches the end of dequeue
> with status COMPLETED was queued to this endpoint and has finished.
> Anything else was never queued here, or the driver lost track of it.
> Keep the error for those, and return success for a completed request.
>
> A completed request still has to be dequeued on the endpoint it belongs
> to. req->dep is set once at allocation and never changes, and
> __dwc3_gadget_ep_queue() rejects the same mismatch with a WARN, so a
> wrong-endpoint dequeue stays on the error path here as well.
>
> This is narrower than the cdnsp fix for the same caller,
> commit 34f08eb0ba6e ("usb: cdnsp: Fixes issue with dequeuing not queued
> requests"), which returns 0 whenever usb_request::status is not
> -EINPROGRESS. That also swallows a request that was never queued, since
> status is zero out of allocation. Going by dwc3's own request status
> keeps that case an error, which is what was asked for when a separate
> ep0 dequeue was proposed in 2022.
>
> Fixes: 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver")
> Cc: stable@vger.kernel.org
> Link: https://lore.kernel.org/linux-usb/20221117054917.30104-1-quic_ugoswami@quicinc.com/
> Assisted-by: LLM sparse
> Signed-off-by: Cole Munz <Munzzyy1@proton.me>
> ---
> All three were missing, sorry about that.
>
> v2: add Fixes:, Cc: stable and Assisted-by tags. No code change.
>
> drivers/usb/dwc3/gadget.c | 19 ++++++++++++++++---
> 1 file changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index fa944856f956..f68eb9254afa 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -2181,9 +2181,22 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
> }
> }
>
> - dev_err(dwc->dev, "request %p was not queued to %s\n",
> - request, ep->name);
> - ret = -EINVAL;
> + /*
> + * The request is on none of this endpoint's lists. That is the
> + * expected state once it has been given back: a function may dequeue
> + * a request before freeing it, and f_fs does so unconditionally for
> + * ep0req in functionfs_unbind(). Nothing is queued, which is what the
> + * caller asked for, so report success. Any other status means the
> + * request was never queued here or the driver lost track of it, and
> + * stays an error. So does a completed request handed to the wrong
> + * endpoint: req->dep is fixed at allocation, and the queue side
> + * rejects the same mismatch.
> + */
LLMs love to add long comments like this that make almost no sense.
Please rewrite this in a human voice, being very concise, if you still
feel a comment is needed.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3] usb: dwc3: gadget: don't error on dequeue of a completed request
2026-09-04 17:07 ` Greg Kroah-Hartman
@ 2026-09-04 20:00 ` Cole Munz
2026-09-04 23:30 ` Thinh Nguyen
0 siblings, 1 reply; 9+ messages in thread
From: Cole Munz @ 2026-09-04 20:00 UTC (permalink / raw)
To: Thinh Nguyen, Greg Kroah-Hartman; +Cc: linux-usb, linux-kernel, stable
Dequeuing a request that has already been given back logs an error and
returns -EINVAL:
dwc3 23000000.usb: request 00000000ad92f1c4 was not queued to ep0out
f_fs hits this on every teardown. functionfs_unbind() dequeues ep0req
unconditionally before freeing it, which
commit ce405d561b02 ("usb: gadget: f_fs: Ensure ep0req is dequeued
before free_request") made deliberate to close a use-after-free. By then
the control transfer has long completed, so dwc3_gadget_ep_dequeue()
finds the request on none of cancelled_list, pending_list or
started_list and falls through to the error path.
Nothing is actually wrong. The request is not queued, which is what the
caller asked for, and both callers ignore the return value and free the
request straight after. The only effect is an error line in every gadget
teardown, which buries real USB errors.
dwc3 already tracks enough to tell the two cases apart.
dwc3_gadget_ep_alloc_request() sets DWC3_REQUEST_STATUS_UNKNOWN, both
__dwc3_gadget_ep_queue() and __dwc3_gadget_ep0_queue() set
DWC3_REQUEST_STATUS_QUEUED, and dwc3_gadget_giveback() sets
DWC3_REQUEST_STATUS_COMPLETED. A request that reaches the end of dequeue
with status COMPLETED was queued to this endpoint and has finished.
Anything else was never queued here, or the driver lost track of it.
Keep the error for those, and return success for a completed request.
A completed request still has to be dequeued on the endpoint it belongs
to. req->dep is set once at allocation and never changes, and
__dwc3_gadget_ep_queue() rejects the same mismatch with a WARN, so a
wrong-endpoint dequeue stays on the error path here as well.
This is narrower than the cdnsp fix for the same caller,
commit 34f08eb0ba6e ("usb: cdnsp: Fixes issue with dequeuing not queued
requests"), which returns 0 whenever usb_request::status is not
-EINPROGRESS. That also swallows a request that was never queued, since
status is zero out of allocation. Going by dwc3's own request status
keeps that case an error, which is what was asked for when a separate
ep0 dequeue was proposed in 2022.
Fixes: 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/linux-usb/20221117054917.30104-1-quic_ugoswami@quicinc.com/
Assisted-by: LLM sparse
Signed-off-by: Cole Munz <Munzzyy1@proton.me>
---
v3: cut the block comment down to one line.
v2: add Fixes:, Cc: stable and Assisted-by tags.
drivers/usb/dwc3/gadget.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index fa944856f956..9ff6a733d3c5 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2181,9 +2181,12 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
}
}
- dev_err(dwc->dev, "request %p was not queued to %s\n",
- request, ep->name);
- ret = -EINVAL;
+ /* Dequeuing a completed request is a no-op, not an error. */
+ if (req->status != DWC3_REQUEST_STATUS_COMPLETED || req->dep != dep) {
+ dev_err(dwc->dev, "request %p was not queued to %s\n",
+ request, ep->name);
+ ret = -EINVAL;
+ }
out:
spin_unlock_irqrestore(&dwc->lock, flags);
--
2.55.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v3] usb: dwc3: gadget: don't error on dequeue of a completed request
2026-09-04 20:00 ` [PATCH v3] " Cole Munz
@ 2026-09-04 23:30 ` Thinh Nguyen
2026-09-05 0:02 ` Cole Munz
0 siblings, 1 reply; 9+ messages in thread
From: Thinh Nguyen @ 2026-09-04 23:30 UTC (permalink / raw)
To: Cole Munz
Cc: Thinh Nguyen, Greg Kroah-Hartman, linux-usb@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
On Fri, Sep 04, 2026, Cole Munz wrote:
> Dequeuing a request that has already been given back logs an error and
> returns -EINVAL:
>
> dwc3 23000000.usb: request 00000000ad92f1c4 was not queued to ep0out
>
> f_fs hits this on every teardown. functionfs_unbind() dequeues ep0req
> unconditionally before freeing it, which
> commit ce405d561b02 ("usb: gadget: f_fs: Ensure ep0req is dequeued
> before free_request") made deliberate to close a use-after-free. By then
> the control transfer has long completed, so dwc3_gadget_ep_dequeue()
> finds the request on none of cancelled_list, pending_list or
> started_list and falls through to the error path.
>
> Nothing is actually wrong. The request is not queued, which is what the
> caller asked for, and both callers ignore the return value and free the
> request straight after. The only effect is an error line in every gadget
> teardown, which buries real USB errors.
>
> dwc3 already tracks enough to tell the two cases apart.
> dwc3_gadget_ep_alloc_request() sets DWC3_REQUEST_STATUS_UNKNOWN, both
> __dwc3_gadget_ep_queue() and __dwc3_gadget_ep0_queue() set
> DWC3_REQUEST_STATUS_QUEUED, and dwc3_gadget_giveback() sets
> DWC3_REQUEST_STATUS_COMPLETED. A request that reaches the end of dequeue
> with status COMPLETED was queued to this endpoint and has finished.
> Anything else was never queued here, or the driver lost track of it.
> Keep the error for those, and return success for a completed request.
>
> A completed request still has to be dequeued on the endpoint it belongs
> to. req->dep is set once at allocation and never changes, and
> __dwc3_gadget_ep_queue() rejects the same mismatch with a WARN, so a
> wrong-endpoint dequeue stays on the error path here as well.
>
> This is narrower than the cdnsp fix for the same caller,
> commit 34f08eb0ba6e ("usb: cdnsp: Fixes issue with dequeuing not queued
> requests"), which returns 0 whenever usb_request::status is not
> -EINPROGRESS. That also swallows a request that was never queued, since
> status is zero out of allocation. Going by dwc3's own request status
> keeps that case an error, which is what was asked for when a separate
> ep0 dequeue was proposed in 2022.
>
> Fixes: 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver")
> Cc: stable@vger.kernel.org
> Link: https://urldefense.com/v3/__https://lore.kernel.org/linux-usb/20221117054917.30104-1-quic_ugoswami@quicinc.com/__;!!A4F2R9G_pg!exBSfbxMvn0256JnM9YGZHRuDHPfgf1X4grkdaDDfYGqfbWTc9oBZslv4KvNpjA_wmWM9R9rXsh508WX1YaBoJs$
> Assisted-by: LLM sparse
> Signed-off-by: Cole Munz <Munzzyy1@proton.me>
> ---
> v3: cut the block comment down to one line.
> v2: add Fixes:, Cc: stable and Assisted-by tags.
>
> drivers/usb/dwc3/gadget.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index fa944856f956..9ff6a733d3c5 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -2181,9 +2181,12 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
> }
> }
>
> - dev_err(dwc->dev, "request %p was not queued to %s\n",
> - request, ep->name);
> - ret = -EINVAL;
> + /* Dequeuing a completed request is a no-op, not an error. */
> + if (req->status != DWC3_REQUEST_STATUS_COMPLETED || req->dep != dep) {
> + dev_err(dwc->dev, "request %p was not queued to %s\n",
> + request, ep->name);
> + ret = -EINVAL;
> + }
> out:
> spin_unlock_irqrestore(&dwc->lock, flags);
>
> --
> 2.55.0
>
>
NAK.
This is not a fix. This changes the dequeue() behavior. You're breaking
the documented behavior of usb_ep_dequeue():
If the request is still active on the endpoint, it is dequeued and
eventually its completion routine is called (with status -ECONNRESET);
else a negative error code is returned. This routine is asynchronous,
that is, it may return before the completion routine runs.
BR,
Thinh
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3] usb: dwc3: gadget: don't error on dequeue of a completed request
2026-09-04 23:30 ` Thinh Nguyen
@ 2026-09-05 0:02 ` Cole Munz
2026-09-05 1:22 ` Thinh Nguyen
0 siblings, 1 reply; 9+ messages in thread
From: Cole Munz @ 2026-09-05 0:02 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: Greg Kroah-Hartman, linux-usb, linux-kernel
On Fri, Sep 04, 2026, Thinh Nguyen wrote:
> NAK.
>
> This is not a fix. This changes the dequeue() behavior. You're breaking
> the documented behavior of usb_ep_dequeue():
You're right, the return value is documented and I shouldn't change it.
The part that actually hurts is the dev_err. f_fs dequeues ep0req on
every teardown on purpose since ce405d561b02, so every unbind logs
dwc3 23000000.usb: request 00000000ad92f1c4 was not queued to ep0out
for a request that completed normally, and that noise buries real
errors. Would you take a version that keeps the -EINVAL return and only
lowers the message to dev_dbg when the request is COMPLETED on its own
endpoint? The never-queued and wrong-endpoint cases would keep the
dev_err.
If that's not worth doing either, I'll drop it.
Regards,
Cole
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3] usb: dwc3: gadget: don't error on dequeue of a completed request
2026-09-05 0:02 ` Cole Munz
@ 2026-09-05 1:22 ` Thinh Nguyen
2026-09-05 2:03 ` Cole Munz
0 siblings, 1 reply; 9+ messages in thread
From: Thinh Nguyen @ 2026-09-05 1:22 UTC (permalink / raw)
To: Cole Munz
Cc: Thinh Nguyen, Greg Kroah-Hartman, linux-usb@vger.kernel.org,
linux-kernel@vger.kernel.org
On Sat, Sep 05, 2026, Cole Munz wrote:
> On Fri, Sep 04, 2026, Thinh Nguyen wrote:
> > NAK.
> >
> > This is not a fix. This changes the dequeue() behavior. You're breaking
> > the documented behavior of usb_ep_dequeue():
>
> You're right, the return value is documented and I shouldn't change it.
>
> The part that actually hurts is the dev_err. f_fs dequeues ep0req on
> every teardown on purpose since ce405d561b02, so every unbind logs
>
> dwc3 23000000.usb: request 00000000ad92f1c4 was not queued to ep0out
>
> for a request that completed normally, and that noise buries real
> errors. Would you take a version that keeps the -EINVAL return and only
> lowers the message to dev_dbg when the request is COMPLETED on its own
> endpoint? The never-queued and wrong-endpoint cases would keep the
> dev_err.
>
> If that's not worth doing either, I'll drop it.
>
Why is functionfs_unbind() calling usb_ep_dequeue() unconditionally
after the request has already completed?
The change ce405d561b02 looks like a workaround for a different issue.
Maybe the fix belongs in f_fs instead of dwc3?
BR,
Thinh
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3] usb: dwc3: gadget: don't error on dequeue of a completed request
2026-09-05 1:22 ` Thinh Nguyen
@ 2026-09-05 2:03 ` Cole Munz
0 siblings, 0 replies; 9+ messages in thread
From: Cole Munz @ 2026-09-05 2:03 UTC (permalink / raw)
To: Thinh Nguyen; +Cc: Greg Kroah-Hartman, linux-usb, linux-kernel
On Sat, Sep 05, 2026, Thinh Nguyen wrote:
> Why is functionfs_unbind() calling usb_ep_dequeue() unconditionally
> after the request has already completed?
>
> The change ce405d561b02 looks like a workaround for a different issue.
> Maybe the fix belongs in f_fs instead of dwc3?
The dequeue there does a real job in one case: teardown racing an ep0
read/write. ffs_ep0_read/write hold ffs->mutex while they sit in
__ffs_ep0_queue_wait(), so functionfs_unbind() dequeues before taking
the mutex. The giveback with -ECONNRESET is what wakes the parked
reader so it can return and drop the mutex, and only then can unbind
free the request. In every other teardown the request completed long
ago and the dequeue is a no-op, which is the case dwc3 complains
about.
f_fs can tell those apart itself. ep0req is only ever queued from
__ffs_ep0_queue_wait(), so set a flag there before usb_ep_queue(),
clear it in ffs_ep0_complete(), and have functionfs_unbind() dequeue
only when it's set. If the completion fires between the check and the
dequeue you can still hit the dwc3 error, but that's a rare race
window where the documented behavior is doing its job, not noise on
every unbind.
If that direction looks right to you I'll send it as an f_fs patch,
Cc'ing Udipto since it revisits ce405d561b02.
Regards,
Cole
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-09-05 2:03 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-04 16:13 [PATCH RESEND] usb: dwc3: gadget: don't error on dequeue of a completed request Cole Munz
2026-09-04 16:16 ` Greg Kroah-Hartman
2026-09-04 16:58 ` [PATCH v2] " Cole Munz
2026-09-04 17:07 ` Greg Kroah-Hartman
2026-09-04 20:00 ` [PATCH v3] " Cole Munz
2026-09-04 23:30 ` Thinh Nguyen
2026-09-05 0:02 ` Cole Munz
2026-09-05 1:22 ` Thinh Nguyen
2026-09-05 2:03 ` Cole Munz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox