usb: dwc3: Do not traverse list using list_for_each_safe

There is a possibility of race between endpoint transfer
completion context and stop active transfer context. As
a result dwc3_gadget_ep_cleanup_completed_requests() iterates
over started_list using list_for_each_safe while
dwc3_remove_requests() is deleting req from started list.
While iterating over current list node list_for_each_safe caches
next list node. If the cached list node is getting deleted by
dwc3_remove_requests() then request for same list node would be
given back as part of endpoint transfer completion. This result
into list_del corruption because list node is getting deleted
twice. Fix this issue by iterating started_list using while loop
and always accessing first node from list head.

Change-Id: I64104a43ade015923deeb1f230a17dea08817052
Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
Signed-off-by: Jack Pham <jackp@codeaurora.org>
This commit is contained in:
Hemant Kumar 2018-11-16 17:24:39 -08:00 • committed by Jack Pham
commit bd1c66bfdb

View file

@ -2804,11 +2804,11 @@ static void dwc3_gadget_ep_cleanup_completed_requests(struct dwc3_ep *dep,
const struct dwc3_event_depevt *event, int status)
{
struct dwc3_request *req;
struct dwc3_request *tmp;
list_for_each_entry_safe(req, tmp, &dep->started_list, list) {
while (!list_empty(&dep->started_list)) {
int ret;
req = next_request(&dep->started_list);
ret = dwc3_gadget_ep_cleanup_completed_request(dep, event,
req, status);
if (ret)