
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 --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; + } } }