diff mbox series

[v2] usb: dwc3: gadget: Reduce TRB IOC settings

Message ID 72a1fa448eb1201b152e65be7902a5d1c75b9f3a.1667867687.git.Thinh.Nguyen@synopsys.com (mailing list archive)
State Accepted
Commit 04914233561377fc0369b984c9d19ec1b6ce2845
Headers show
Series [v2] usb: dwc3: gadget: Reduce TRB IOC settings | expand

Commit Message

Thinh Nguyen Nov. 8, 2022, 12:37 a.m. UTC
When the TRB ring is full, the dwc3 driver must make sure that there's
at least 1 TRB with Interrupt On Completion (IOC) set to notify of
available TRBs.

The current logic just sets the TRB's IOC whenever we run out of TRBs,
but it doesn't consider that there may be other TRBs with IOC/LST set
already. This creates more events and unnecessary delay from interrupt
handling. Only forcefully set IOC when we run out of TRBs and none of
the TRBs in the TRB ring has had IOC set.

Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
---
 Changes in v2:
 - The previous version assumes all requests have interrupt on
   completion set. We must check for the request's no_interrupt setting
   also.
 - Remove unnecessary note in commit.

 drivers/usb/dwc3/gadget.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)


base-commit: a8bc8cc193c69e41df5e757d1a592346526e136d
diff mbox series

Patch

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 5fe2d136dff5..ecddb144871b 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1463,8 +1463,18 @@  static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
 			 */
 			if (num_trbs_left == 1 || (needs_extra_trb &&
 					num_trbs_left <= 2 &&
-					sg_dma_len(sg_next(s)) >= length))
-				must_interrupt = true;
+					sg_dma_len(sg_next(s)) >= length)) {
+				struct dwc3_request *r;
+
+				/* Check if previous requests already set IOC */
+				list_for_each_entry(r, &dep->started_list, list) {
+					if (r != req && !r->request.no_interrupt)
+						break;
+
+					if (r == req)
+						must_interrupt = true;
+				}
+			}
 
 			dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false,
 					must_interrupt);