Skip to content

Commit 69c58de

Browse files
Badhri Jagan Sridharangregkh
authored andcommitted
usb: dwc3: gadget: Prevent irq storm when TH re-executes
While commit d325a1d ("usb: dwc3: gadget: Prevent losing events in event cache") makes sure that top half(TH) does not end up overwriting the cached events before processing them when the TH gets invoked more than one time, returning IRQ_HANDLED results in occasional irq storm where the TH hogs the CPU. The irq storm can be prevented by the flag before event handler busy is cleared. Default enable interrupt moderation in all versions which support them. ftrace event stub during dwc3 irq storm: irq/504_dwc3-1111 ( 1111) [000] .... 70.000866: irq_handler_exit: irq=14 ret=handled irq/504_dwc3-1111 ( 1111) [000] .... 70.000872: irq_handler_entry: irq=504 name=dwc3 irq/504_dwc3-1111 ( 1111) [000] .... 70.000874: irq_handler_exit: irq=504 ret=handled irq/504_dwc3-1111 ( 1111) [000] .... 70.000881: irq_handler_entry: irq=504 name=dwc3 irq/504_dwc3-1111 ( 1111) [000] .... 70.000883: irq_handler_exit: irq=504 ret=handled irq/504_dwc3-1111 ( 1111) [000] .... 70.000889: irq_handler_entry: irq=504 name=dwc3 irq/504_dwc3-1111 ( 1111) [000] .... 70.000892: irq_handler_exit: irq=504 ret=handled irq/504_dwc3-1111 ( 1111) [000] .... 70.000898: irq_handler_entry: irq=504 name=dwc3 irq/504_dwc3-1111 ( 1111) [000] .... 70.000901: irq_handler_exit: irq=504 ret=handled irq/504_dwc3-1111 ( 1111) [000] .... 70.000907: irq_handler_entry: irq=504 name=dwc3 irq/504_dwc3-1111 ( 1111) [000] .... 70.000909: irq_handler_exit: irq=504 ret=handled irq/504_dwc3-1111 ( 1111) [000] .... 70.000915: irq_handler_entry: irq=504 name=dwc3 irq/504_dwc3-1111 ( 1111) [000] .... 70.000918: irq_handler_exit: irq=504 ret=handled irq/504_dwc3-1111 ( 1111) [000] .... 70.000924: irq_handler_entry: irq=504 name=dwc3 irq/504_dwc3-1111 ( 1111) [000] .... 70.000927: irq_handler_exit: irq=504 ret=handled irq/504_dwc3-1111 ( 1111) [000] .... 70.000933: irq_handler_entry: irq=504 name=dwc3 irq/504_dwc3-1111 ( 1111) [000] .... 70.000935: irq_handler_exit: irq=504 ret=handled .... Cc: stable <stable@kernel.org> Suggested-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Fixes: d325a1d ("usb: dwc3: gadget: Prevent losing events in event cache") Signed-off-by: Badhri Jagan Sridharan <badhri@google.com> Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/20250216223003.3568039-1-badhri@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 8e812e9 commit 69c58de

File tree

2 files changed

+13
-13
lines changed

2 files changed

+13
-13
lines changed

drivers/usb/dwc3/core.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,8 +1835,6 @@ static void dwc3_get_properties(struct dwc3 *dwc)
18351835
dwc->tx_thr_num_pkt_prd = tx_thr_num_pkt_prd;
18361836
dwc->tx_max_burst_prd = tx_max_burst_prd;
18371837

1838-
dwc->imod_interval = 0;
1839-
18401838
dwc->tx_fifo_resize_max_num = tx_fifo_resize_max_num;
18411839
}
18421840

@@ -1854,21 +1852,19 @@ static void dwc3_check_params(struct dwc3 *dwc)
18541852
unsigned int hwparam_gen =
18551853
DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3);
18561854

1857-
/* Check for proper value of imod_interval */
1858-
if (dwc->imod_interval && !dwc3_has_imod(dwc)) {
1859-
dev_warn(dwc->dev, "Interrupt moderation not supported\n");
1860-
dwc->imod_interval = 0;
1861-
}
1862-
18631855
/*
1856+
* Enable IMOD for all supporting controllers.
1857+
*
1858+
* Particularly, DWC_usb3 v3.00a must enable this feature for
1859+
* the following reason:
1860+
*
18641861
* Workaround for STAR 9000961433 which affects only version
18651862
* 3.00a of the DWC_usb3 core. This prevents the controller
18661863
* interrupt from being masked while handling events. IMOD
18671864
* allows us to work around this issue. Enable it for the
18681865
* affected version.
18691866
*/
1870-
if (!dwc->imod_interval &&
1871-
DWC3_VER_IS(DWC3, 300A))
1867+
if (dwc3_has_imod((dwc)))
18721868
dwc->imod_interval = 1;
18731869

18741870
/* Check the maximum_speed parameter */

drivers/usb/dwc3/gadget.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4501,14 +4501,18 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt)
45014501
dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
45024502
DWC3_GEVNTSIZ_SIZE(evt->length));
45034503

4504+
evt->flags &= ~DWC3_EVENT_PENDING;
4505+
/*
4506+
* Add an explicit write memory barrier to make sure that the update of
4507+
* clearing DWC3_EVENT_PENDING is observed in dwc3_check_event_buf()
4508+
*/
4509+
wmb();
4510+
45044511
if (dwc->imod_interval) {
45054512
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB);
45064513
dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), dwc->imod_interval);
45074514
}
45084515

4509-
/* Keep the clearing of DWC3_EVENT_PENDING at the end */
4510-
evt->flags &= ~DWC3_EVENT_PENDING;
4511-
45124516
return ret;
45134517
}
45144518

0 commit comments

Comments
 (0)