* [PATCH 1/1] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count
@ 2026-07-27 9:40 Jiazi Liu
2026-08-04 23:04 ` Thinh Nguyen
2026-08-06 9:03 ` kernel test robot
0 siblings, 2 replies; 5+ messages in thread
From: Jiazi Liu @ 2026-07-27 9:40 UTC (permalink / raw)
To: Thinh.Nguyen; +Cc: gregkh, linux-usb, linux-kernel, stable, Jiazi Liu
When dwc3_check_event_buf() reads a GEVNTCOUNT value exceeding the
event buffer length, commit 63ccd26cd1f6 ("usb: dwc3: gadget: check
that event count does not exceed event buffer length") returns IRQ_NONE
without writing back GEVNTCOUNT. Since the DWC3 interrupt is
level-triggered, the uncleared IRQ source keeps the line asserted,
causing a tight IRQ storm that accumulates 99,900 unhandled interrupts
and triggers spurious.c:184 BUG -> kernel panic.
The resulting call stack:
__report_bad_irq+0xac/0xc8
note_interrupt+0x340/0x468
handle_irq_event+0xac/0xc0
handle_fasteoi_irq+0x120/0x228
gic_handle_irq+0x68/0x108
...
kernel BUG at kernel/irq/spurious.c:184
To reproduce, write a bogus value exceeding the event buffer length
directly to the GEVNTCOUNT register:
devmem <DWC3_BASE + 0xc40c> 4 0x1004
Write the bogus count back to GEVNTCOUNT to clear the IRQ source,
consistent with the stale event clearing pattern in
dwc3_event_buffers_setup(), and schedule a soft disconnect via
softcon_work to recover the controller state.
Fixes: 63ccd26cd1f6 ("usb: dwc3: gadget: check that event count does not exceed event buffer length")
Cc: stable@vger.kernel.org
Signed-off-by: Jiazi Liu <liujiazi@amazon.com>
---
drivers/usb/dwc3/core.h | 2 ++
drivers/usb/dwc3/gadget.c | 23 ++++++++++++++++++++++-
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 608daeb7ef10..0881ed7e956e 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1004,6 +1004,7 @@ struct dwc3_glue_ops {
/**
* struct dwc3 - representation of our controller
* @drd_work: workqueue used for role swapping
+ * @softcon_work: workqueue used for soft connect/disconnect recovery
* @ep0_trb: trb which is used for the ctrl_req
* @bounce: address of bounce buffer
* @setup_buf: used while precessing STD USB requests
@@ -1189,6 +1190,7 @@ struct dwc3_glue_ops {
*/
struct dwc3 {
struct work_struct drd_work;
+ struct work_struct softcon_work;
struct dwc3_trb *ep0_trb;
void *bounce;
u8 *setup_buf;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index fa0f16ffafef..9b24259272a4 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -4669,7 +4669,18 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
if (count > evt->length) {
dev_err_ratelimited(dwc->dev, "invalid count(%u) > evt->length(%u)\n",
count, evt->length);
- return IRQ_NONE;
+ /*
+ * The DWC3 interrupt is level-triggered. Returning IRQ_NONE
+ * without clearing the IRQ source leaves the line asserted,
+ * causing a tight IRQ storm that triggers spurious.c:184 BUG.
+ * Write the bogus count back to GEVNTCOUNT to clear the source,
+ * consistent with the stale event clearing in
+ * dwc3_event_buffers_setup(), then schedule a soft disconnect
+ * to recover the controller state.
+ */
+ dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count);
+ schedule_work(&dwc->softcon_work);
+ return IRQ_HANDLED;
}
evt->count = count;
@@ -4729,6 +4740,14 @@ static void dwc_gadget_release(struct device *dev)
kfree(gadget);
}
+static void dwc3_softcon_work(struct work_struct *work)
+{
+ struct dwc3 *dwc = container_of(work, struct dwc3, softcon_work);
+
+ dev_err(dwc->dev, "event buffer error: performing soft disconnect\n");
+ dwc3_gadget_soft_disconnect(dwc);
+}
+
/**
* dwc3_gadget_init - initializes gadget related registers
* @dwc: pointer to our controller context structure
@@ -4772,6 +4791,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
}
init_completion(&dwc->ep0_in_setup);
+ INIT_WORK(&dwc->softcon_work, dwc3_softcon_work);
dwc->gadget = kzalloc_obj(struct usb_gadget);
if (!dwc->gadget) {
ret = -ENOMEM;
@@ -4868,6 +4888,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
if (!dwc->gadget)
return;
+ cancel_work_sync(&dwc->softcon_work);
dwc3_enable_susphy(dwc, true);
usb_del_gadget(dwc->gadget);
dwc3_gadget_free_endpoints(dwc);
--
2.50.1 (Apple Git-155)
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/1] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count
2026-07-27 9:40 [PATCH 1/1] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count Jiazi Liu
@ 2026-08-04 23:04 ` Thinh Nguyen
2026-08-06 9:03 ` kernel test robot
1 sibling, 0 replies; 5+ messages in thread
From: Thinh Nguyen @ 2026-08-04 23:04 UTC (permalink / raw)
To: Jiazi Liu
Cc: Thinh Nguyen, gregkh@linuxfoundation.org,
linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org, Jiazi Liu
On Mon, Jul 27, 2026, Jiazi Liu wrote:
> When dwc3_check_event_buf() reads a GEVNTCOUNT value exceeding the
> event buffer length, commit 63ccd26cd1f6 ("usb: dwc3: gadget: check
> that event count does not exceed event buffer length") returns IRQ_NONE
> without writing back GEVNTCOUNT. Since the DWC3 interrupt is
> level-triggered, the uncleared IRQ source keeps the line asserted,
> causing a tight IRQ storm that accumulates 99,900 unhandled interrupts
> and triggers spurious.c:184 BUG -> kernel panic.
>
> The resulting call stack:
> __report_bad_irq+0xac/0xc8
> note_interrupt+0x340/0x468
> handle_irq_event+0xac/0xc0
> handle_fasteoi_irq+0x120/0x228
> gic_handle_irq+0x68/0x108
> ...
> kernel BUG at kernel/irq/spurious.c:184
>
> To reproduce, write a bogus value exceeding the event buffer length
> directly to the GEVNTCOUNT register:
>
> devmem <DWC3_BASE + 0xc40c> 4 0x1004
>
> Write the bogus count back to GEVNTCOUNT to clear the IRQ source,
> consistent with the stale event clearing pattern in
> dwc3_event_buffers_setup(), and schedule a soft disconnect via
> softcon_work to recover the controller state.
>
> Fixes: 63ccd26cd1f6 ("usb: dwc3: gadget: check that event count does not exceed event buffer length")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jiazi Liu <liujiazi@amazon.com>
> ---
> drivers/usb/dwc3/core.h | 2 ++
> drivers/usb/dwc3/gadget.c | 23 ++++++++++++++++++++++-
> 2 files changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index 608daeb7ef10..0881ed7e956e 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -1004,6 +1004,7 @@ struct dwc3_glue_ops {
> /**
> * struct dwc3 - representation of our controller
> * @drd_work: workqueue used for role swapping
> + * @softcon_work: workqueue used for soft connect/disconnect recovery
Rename this to err_recovery_work and update the description.
> * @ep0_trb: trb which is used for the ctrl_req
> * @bounce: address of bounce buffer
> * @setup_buf: used while precessing STD USB requests
> @@ -1189,6 +1190,7 @@ struct dwc3_glue_ops {
> */
> struct dwc3 {
> struct work_struct drd_work;
> + struct work_struct softcon_work;
> struct dwc3_trb *ep0_trb;
> void *bounce;
> u8 *setup_buf;
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index fa0f16ffafef..9b24259272a4 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -4669,7 +4669,18 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
> if (count > evt->length) {
> dev_err_ratelimited(dwc->dev, "invalid count(%u) > evt->length(%u)\n",
> count, evt->length);
We probably no longer need the dev_err to be ratelimited.
> - return IRQ_NONE;
> + /*
> + * The DWC3 interrupt is level-triggered. Returning IRQ_NONE
This comment is out of context now that it's no longer IRQ_NONE. Most of
the details here are only relevant if we return IRQ_NONE. What we need
to document here why this is a fatal error and require reinitializing
the controller. Document that the driver and the controller are out of
sync to which event is consumed.
> + * without clearing the IRQ source leaves the line asserted,
> + * causing a tight IRQ storm that triggers spurious.c:184 BUG.
> + * Write the bogus count back to GEVNTCOUNT to clear the source,
> + * consistent with the stale event clearing in
> + * dwc3_event_buffers_setup(), then schedule a soft disconnect
> + * to recover the controller state.
> + */
> + dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count);
> + schedule_work(&dwc->softcon_work);
> + return IRQ_HANDLED;
> }
>
> evt->count = count;
> @@ -4729,6 +4740,14 @@ static void dwc_gadget_release(struct device *dev)
> kfree(gadget);
> }
>
> +static void dwc3_softcon_work(struct work_struct *work)
> +{
> + struct dwc3 *dwc = container_of(work, struct dwc3, softcon_work);
> +
> + dev_err(dwc->dev, "event buffer error: performing soft disconnect\n");
Remove this dev_err(). The error message should be at the caller where
the specific failure condition is known, not the generic work handler.
> + dwc3_gadget_soft_disconnect(dwc);
Check and follow the dwc3_gadget_suspend() and dwc3_gadget_resume()
logic for soft-disconnect and soft-connect to make sure the internal
states are updated and notify the gadget drivers correctly.
Perhaps you can also recover with soft-connect after soft-disconnect.
> +}
> +
> /**
> * dwc3_gadget_init - initializes gadget related registers
> * @dwc: pointer to our controller context structure
> @@ -4772,6 +4791,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
> }
>
> init_completion(&dwc->ep0_in_setup);
> + INIT_WORK(&dwc->softcon_work, dwc3_softcon_work);
> dwc->gadget = kzalloc_obj(struct usb_gadget);
> if (!dwc->gadget) {
> ret = -ENOMEM;
> @@ -4868,6 +4888,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
> if (!dwc->gadget)
> return;
>
> + cancel_work_sync(&dwc->softcon_work);
> dwc3_enable_susphy(dwc, true);
> usb_del_gadget(dwc->gadget);
> dwc3_gadget_free_endpoints(dwc);
> --
> 2.50.1 (Apple Git-155)
>
Thanks,
Thinh
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/1] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count
2026-07-27 9:40 [PATCH 1/1] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count Jiazi Liu
2026-08-04 23:04 ` Thinh Nguyen
@ 2026-08-06 9:03 ` kernel test robot
2026-08-07 11:04 ` Liu Jiazi
1 sibling, 1 reply; 5+ messages in thread
From: kernel test robot @ 2026-08-06 9:03 UTC (permalink / raw)
To: Jiazi Liu, Thinh.Nguyen
Cc: oe-kbuild-all, gregkh, linux-usb, linux-kernel, stable, Jiazi Liu
Hi Jiazi,
kernel test robot noticed the following build warnings:
[auto build test WARNING on usb/usb-testing]
[also build test WARNING on usb/usb-next usb/usb-linus linus/master v7.2-rc6 next-20260805]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Jiazi-Liu/usb-dwc3-gadget-fix-IRQ-storm-on-invalid-event-buffer-count/20260806-005046
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
patch link: https://lore.kernel.org/r/20260727094015.5101-1-liujiazi%40amazon.com
patch subject: [PATCH 1/1] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count
config: i386-randconfig-r132-20260806 (https://download.01.org/0day-ci/archive/20260806/202608061759.sIcC6h4C-lkp@intel.com/config)
compiler: gcc-13 (Debian 13.3.0-16) 13.3.0
sparse: v0.6.5-rc1
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260806/202608061759.sIcC6h4C-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608061759.sIcC6h4C-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
>> drivers/usb/dwc3/gadget.c:4681:32: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct dwc3 *dwc @@ got void [noderef] __iomem *regs @@
drivers/usb/dwc3/gadget.c:4681:32: sparse: expected struct dwc3 *dwc
drivers/usb/dwc3/gadget.c:4681:32: sparse: got void [noderef] __iomem *regs
vim +4681 drivers/usb/dwc3/gadget.c
4636
4637 static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
4638 {
4639 struct dwc3 *dwc = evt->dwc;
4640 u32 amount;
4641 u32 count;
4642
4643 if (pm_runtime_suspended(dwc->dev)) {
4644 dwc->pending_events = true;
4645 /*
4646 * Trigger runtime resume. The get() function will be balanced
4647 * after processing the pending events in dwc3_process_pending
4648 * events().
4649 */
4650 pm_runtime_get(dwc->dev);
4651 disable_irq_nosync(dwc->irq_gadget);
4652 return IRQ_HANDLED;
4653 }
4654
4655 /*
4656 * With PCIe legacy interrupt, test shows that top-half irq handler can
4657 * be called again after HW interrupt deassertion. Check if bottom-half
4658 * irq event handler completes before caching new event to prevent
4659 * losing events.
4660 */
4661 if (evt->flags & DWC3_EVENT_PENDING)
4662 return IRQ_HANDLED;
4663
4664 count = dwc3_readl(dwc, DWC3_GEVNTCOUNT(0));
4665 count &= DWC3_GEVNTCOUNT_MASK;
4666 if (!count)
4667 return IRQ_NONE;
4668
4669 if (count > evt->length) {
4670 dev_err_ratelimited(dwc->dev, "invalid count(%u) > evt->length(%u)\n",
4671 count, evt->length);
4672 /*
4673 * The DWC3 interrupt is level-triggered. Returning IRQ_NONE
4674 * without clearing the IRQ source leaves the line asserted,
4675 * causing a tight IRQ storm that triggers spurious.c:184 BUG.
4676 * Write the bogus count back to GEVNTCOUNT to clear the source,
4677 * consistent with the stale event clearing in
4678 * dwc3_event_buffers_setup(), then schedule a soft disconnect
4679 * to recover the controller state.
4680 */
> 4681 dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count);
4682 schedule_work(&dwc->softcon_work);
4683 return IRQ_HANDLED;
4684 }
4685
4686 evt->count = count;
4687 evt->flags |= DWC3_EVENT_PENDING;
4688
4689 /* Mask interrupt */
4690 dwc3_writel(dwc, DWC3_GEVNTSIZ(0),
4691 DWC3_GEVNTSIZ_INTMASK | DWC3_GEVNTSIZ_SIZE(evt->length));
4692
4693 amount = min(count, evt->length - evt->lpos);
4694 memcpy(evt->cache + evt->lpos, evt->buf + evt->lpos, amount);
4695
4696 if (amount < count)
4697 memcpy(evt->cache, evt->buf, count - amount);
4698
4699 dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), count);
4700
4701 return IRQ_WAKE_THREAD;
4702 }
4703
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/1] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count
2026-08-06 9:03 ` kernel test robot
@ 2026-08-07 11:04 ` Liu Jiazi
2026-08-07 23:09 ` Thinh Nguyen
0 siblings, 1 reply; 5+ messages in thread
From: Liu Jiazi @ 2026-08-07 11:04 UTC (permalink / raw)
To: kernel test robot
Cc: Thinh.Nguyen, oe-kbuild-all, gregkh, linux-usb, linux-kernel,
stable, Jiazi Liu
Hi @Thinh.Nguyen@synopsys.com
Thanks for the review suggestions. I've updated the patch accordingly.
On thing I'd like to discuss: in dwc3_err_recovery_work(), after
soft_disconnect succeeds, should we attempt soft_connect to
recover the controller, or just leave it disconnected and let the
upper layer (e.g. function driver like ADB) handle reconnection
on its own?
In my testing, calling soft_connect after soft_disconnect triggers an
RCU stall. Simply doing soft_disconnect and notifying the
gadget driver via dwc3_disconnect_gadget_sleepable() is sufficient —
ADB recovers on its own after that.
What's your recommendation here?
Brs
Jiazi
kernel test robot <lkp@intel.com> 于2026年8月6日周四 17:03写道:
>
> Hi Jiazi,
>
> kernel test robot noticed the following build warnings:
>
> [auto build test WARNING on usb/usb-testing]
> [also build test WARNING on usb/usb-next usb/usb-linus linus/master v7.2-rc6 next-20260805]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url: https://github.com/intel-lab-lkp/linux/commits/Jiazi-Liu/usb-dwc3-gadget-fix-IRQ-storm-on-invalid-event-buffer-count/20260806-005046
> base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
> patch link: https://lore.kernel.org/r/20260727094015.5101-1-liujiazi%40amazon.com
> patch subject: [PATCH 1/1] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count
> config: i386-randconfig-r132-20260806 (https://download.01.org/0day-ci/archive/20260806/202608061759.sIcC6h4C-lkp@intel.com/config)
> compiler: gcc-13 (Debian 13.3.0-16) 13.3.0
> sparse: v0.6.5-rc1
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260806/202608061759.sIcC6h4C-lkp@intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202608061759.sIcC6h4C-lkp@intel.com/
>
> sparse warnings: (new ones prefixed by >>)
> >> drivers/usb/dwc3/gadget.c:4681:32: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct dwc3 *dwc @@ got void [noderef] __iomem *regs @@
> drivers/usb/dwc3/gadget.c:4681:32: sparse: expected struct dwc3 *dwc
> drivers/usb/dwc3/gadget.c:4681:32: sparse: got void [noderef] __iomem *regs
>
> vim +4681 drivers/usb/dwc3/gadget.c
>
> 4636
> 4637 static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
> 4638 {
> 4639 struct dwc3 *dwc = evt->dwc;
> 4640 u32 amount;
> 4641 u32 count;
> 4642
> 4643 if (pm_runtime_suspended(dwc->dev)) {
> 4644 dwc->pending_events = true;
> 4645 /*
> 4646 * Trigger runtime resume. The get() function will be balanced
> 4647 * after processing the pending events in dwc3_process_pending
> 4648 * events().
> 4649 */
> 4650 pm_runtime_get(dwc->dev);
> 4651 disable_irq_nosync(dwc->irq_gadget);
> 4652 return IRQ_HANDLED;
> 4653 }
> 4654
> 4655 /*
> 4656 * With PCIe legacy interrupt, test shows that top-half irq handler can
> 4657 * be called again after HW interrupt deassertion. Check if bottom-half
> 4658 * irq event handler completes before caching new event to prevent
> 4659 * losing events.
> 4660 */
> 4661 if (evt->flags & DWC3_EVENT_PENDING)
> 4662 return IRQ_HANDLED;
> 4663
> 4664 count = dwc3_readl(dwc, DWC3_GEVNTCOUNT(0));
> 4665 count &= DWC3_GEVNTCOUNT_MASK;
> 4666 if (!count)
> 4667 return IRQ_NONE;
> 4668
> 4669 if (count > evt->length) {
> 4670 dev_err_ratelimited(dwc->dev, "invalid count(%u) > evt->length(%u)\n",
> 4671 count, evt->length);
> 4672 /*
> 4673 * The DWC3 interrupt is level-triggered. Returning IRQ_NONE
> 4674 * without clearing the IRQ source leaves the line asserted,
> 4675 * causing a tight IRQ storm that triggers spurious.c:184 BUG.
> 4676 * Write the bogus count back to GEVNTCOUNT to clear the source,
> 4677 * consistent with the stale event clearing in
> 4678 * dwc3_event_buffers_setup(), then schedule a soft disconnect
> 4679 * to recover the controller state.
> 4680 */
> > 4681 dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count);
> 4682 schedule_work(&dwc->softcon_work);
> 4683 return IRQ_HANDLED;
> 4684 }
> 4685
> 4686 evt->count = count;
> 4687 evt->flags |= DWC3_EVENT_PENDING;
> 4688
> 4689 /* Mask interrupt */
> 4690 dwc3_writel(dwc, DWC3_GEVNTSIZ(0),
> 4691 DWC3_GEVNTSIZ_INTMASK | DWC3_GEVNTSIZ_SIZE(evt->length));
> 4692
> 4693 amount = min(count, evt->length - evt->lpos);
> 4694 memcpy(evt->cache + evt->lpos, evt->buf + evt->lpos, amount);
> 4695
> 4696 if (amount < count)
> 4697 memcpy(evt->cache, evt->buf, count - amount);
> 4698
> 4699 dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), count);
> 4700
> 4701 return IRQ_WAKE_THREAD;
> 4702 }
> 4703
>
> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/1] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count
2026-08-07 11:04 ` Liu Jiazi
@ 2026-08-07 23:09 ` Thinh Nguyen
0 siblings, 0 replies; 5+ messages in thread
From: Thinh Nguyen @ 2026-08-07 23:09 UTC (permalink / raw)
To: Liu Jiazi
Cc: kernel test robot, Thinh Nguyen, oe-kbuild-all@lists.linux.dev,
gregkh@linuxfoundation.org, linux-usb@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org, Jiazi Liu
Hi Liu Jiazi,
On Fri, Aug 07, 2026, Liu Jiazi wrote:
> Hi @Thinh.Nguyen@synopsys.com
>
> Thanks for the review suggestions. I've updated the patch accordingly.
> On thing I'd like to discuss: in dwc3_err_recovery_work(), after
> soft_disconnect succeeds, should we attempt soft_connect to
> recover the controller, or just leave it disconnected and let the
> upper layer (e.g. function driver like ADB) handle reconnection
> on its own?
But what would trigger the usb core to reconnect?
>
> In my testing, calling soft_connect after soft_disconnect triggers an
Can you confirm where exactly the RCU stall happens? Did you add
synchronize_irq() before the soft_connect?
> RCU stall. Simply doing soft_disconnect and notifying the
> gadget driver via dwc3_disconnect_gadget_sleepable() is sufficient —
> ADB recovers on its own after that.
> What's your recommendation here?
>
> Brs
> Jiazi
>
Also, we may need to add a resuscitate counter and a "dying" state.
Before scheduling the dwc3_err_recovery_work(), increment the counter
and set the dying state. While in this state, the controller should
reject all gadget driver's requests.
If we fail to recover more than 3 times, stop doing soft_connect.
BR,
Thinh
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-08-07 23:09 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-27 9:40 [PATCH 1/1] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count Jiazi Liu
2026-08-04 23:04 ` Thinh Nguyen
2026-08-06 9:03 ` kernel test robot
2026-08-07 11:04 ` Liu Jiazi
2026-08-07 23:09 ` Thinh Nguyen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox