Re: [PATCH v2 1/1] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count
From: Krishna Kurapati
Date: Wed Aug 12 2026 - 06:04:41 EST
On 8/12/2026 1:51 PM, Jiazi Liu wrote:
From: Jiazi Liu <jiazi.liu1984@xxxxxxxxx>
[...]
---
drivers/usb/dwc3/core.h | 7 +++++++
drivers/usb/dwc3/gadget.c | 41 +++++++++++++++++++++++++++++++++++++--
2 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 608daeb7ef10..b1cd888eca77 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -49,6 +49,7 @@
#define DWC3_ENDPOINTS_NUM 32
#define DWC3_XHCI_RESOURCES_NUM 2
#define DWC3_ISOC_MAX_RETRIES 5
+#define DWC3_ERR_RECOVERY_MAX 3
#define DWC3_SCRATCHBUF_SIZE 4096 /* each buffer is assumed to be 4KiB */
#define DWC3_EVENT_BUFFERS_SIZE 4096
@@ -1004,6 +1005,7 @@ struct dwc3_glue_ops {
/**
* struct dwc3 - representation of our controller
* @drd_work: workqueue used for role swapping
+ * @err_recovery_work: workqueue used for controller error recovery
* @ep0_trb: trb which is used for the ctrl_req
* @bounce: address of bounce buffer
* @setup_buf: used while precessing STD USB requests
@@ -1171,6 +1173,7 @@ struct dwc3_glue_ops {
* @wakeup_configured: set if the device is configured for remote wakeup.
* @suspended: set to track suspend event due to U3/L2.
* @susphy_state: state of DWC3_GUSB2PHYCFG_SUSPHY + DWC3_GUSB3PIPECTL_SUSPHY
+ * @err_dying: true when controller is in error recovery, reject all requests
* before PM suspend.
How about gadget_dying or gadget_died (similar to hc_died in xhci). The variable "err_dyring"is misleading.
* @imod_interval: set the interrupt moderation interval in 250ns
* increments or 0 to disable.
@@ -1186,9 +1189,11 @@ struct dwc3_glue_ops {
* @wakeup_pending_funcs: Indicates whether any interface has requested for
* function wakeup in bitmap format where bit position
* represents interface_id.
+ * @err_recovery_count: number of consecutive error recovery attempts
*/
struct dwc3 {
struct work_struct drd_work;
+ struct work_struct err_recovery_work;
struct dwc3_trb *ep0_trb;
void *bounce;
u8 *setup_buf;
@@ -1420,6 +1425,7 @@ struct dwc3 {
unsigned wakeup_configured:1;
unsigned suspended:1;
unsigned susphy_state:1;
+ unsigned err_dying:1;
u16 imod_interval;
@@ -1429,6 +1435,7 @@ struct dwc3 {
struct dentry *debug_root;
u32 gsbuscfg0_reqinfo;
u32 wakeup_pending_funcs;
+ u32 err_recovery_count;
};
#define INCRX_BURST_MODE 0
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index fa0f16ffafef..05f3ffab6e47 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2054,6 +2054,9 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
int ret;
+ if (dwc->err_dying)
+ return -ESHUTDOWN;
+
Not sure but should this check be added for all gadget_ops ?
Regards,
Krishna,