diff mbox series

[RFC] usb: dwc3: gadget: workaround for Netconsole hang

Message ID 20230123144724.1291327-1-lusus@denx.de
State RFC
Delegated to: Marek Vasut
Headers show
Series [RFC] usb: dwc3: gadget: workaround for Netconsole hang | expand

Commit Message

Niel Fourie Jan. 23, 2023, 2:47 p.m. UTC
In dwc3_remove_requests(), the while loops clearing out request
lists req_queued and request_list may loop infinitely as the last
remaining elements in these lists end up not pointing to their
respective list_head structures. This workaround detects and
replaces the last element with the expected list_head to break out
of these loops. No memory is leaked as the previous last element gets
reused.

This issue occurs when Netconsole is active over Ethernet gadget,
and the cause it is still unclear. Any ideas?

Signed-off-by: Niel Fourie <lusus@denx.de>
Cc: Marek Vasut <marex@denx.de>
---
 drivers/usb/dwc3/gadget.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
diff mbox series

Patch

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index eb416b832a..61f3e367cb 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -538,6 +538,14 @@  static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
 			req = next_request(&dep->req_queued);
 
 			dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
+			/* FIXME! */
+			if (dep->req_queued.next == dep->req_queued.prev &&
+			    dep->req_queued.next != &dep->req_queued) {
+				printf("Stuck? Emptying req_queued... head=%lx, next=%lx;\n",
+				       (ulong)&dep->req_queued, (ulong)dep->req_queued.next);
+				dep->req_queued.next = &dep->req_queued;
+				dep->req_queued.prev = &dep->req_queued;
+			}
 		}
 	}
 
@@ -545,6 +553,14 @@  static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
 		req = next_request(&dep->request_list);
 
 		dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
+		/* FIXME! */
+		if (dep->request_list.next == dep->request_list.prev &&
+		    dep->request_list.next != &dep->request_list) {
+			printf("Stuck? Emptying request_list... head=%lx, next=%lx;\n",
+			       (ulong)&dep->request_list, (ulong)dep->request_list.next);
+			dep->request_list.next = &dep->request_list;
+			dep->request_list.prev = &dep->request_list;
+		}
 	}
 }