Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 25ebbe64 authored by Hemant Kumar's avatar Hemant Kumar Committed by Gerrit - the friendly Code Review server
Browse files

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_cleanup_done_reqs() 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: default avatarHemant Kumar <hemantk@codeaurora.org>
Signed-off-by: default avatarAjay Agarwal <ajaya@codeaurora.org>
parent 825bbb8d
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -2690,16 +2690,17 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep,
static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
		const struct dwc3_event_depevt *event, int status)
{
	struct dwc3_request	*req, *n;
	struct dwc3_request	*req;
	struct dwc3_trb		*trb;
	bool			ioc = false;
	int			ret;

	list_for_each_entry_safe(req, n, &dep->started_list, list) {
	while (!list_empty(&dep->started_list)) {
		unsigned length;
		unsigned actual;
		int chain;

		req = next_request(&dep->started_list);
		if (req->trb->ctrl & DWC3_TRB_CTRL_HWO)
			return 0;