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

Commit 970a014b authored by Udipto Goswami's avatar Udipto Goswami
Browse files

usb: dwc3: Handle race between remove_request and ep_dequeue



Commit 3ef97296 ("usb: dwc3: gadget: Handle race between
remove_request & ep_dequeue") was introduced to fix the race
between remove_requests & dequeue process,but it exposes a new
issue where we see crash on ep_set_halt where the started list
gets corrupted since composite cleanup already did a free_req.

Fix this by reverting the older patch and handling the race
of remove_requests & dequeue in cleanup_cancelled_request
by iterating over the list using while loop which will insure
to access the first node from list_head.

Change-Id: I727ca54e5ac839ceb55efb644a7cd8d514db63b6
Signed-off-by: default avatarUdipto Goswami <ugoswami@codeaurora.org>
parent 8e8bbdac
Loading
Loading
Loading
Loading
+5 −9
Original line number Diff line number Diff line
@@ -1778,11 +1778,11 @@ static void dwc3_gadget_ep_skip_trbs(struct dwc3_ep *dep, struct dwc3_request *r
static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep)
{
	struct dwc3_request		*req;
	struct dwc3_request		*tmp;
	struct dwc3			*dwc = dep->dwc;
	int				request_count = 0;

	list_for_each_entry_safe(req, tmp, &dep->cancelled_list, list) {
	while (!list_empty(&dep->cancelled_list)) {
		req = next_request(&dep->cancelled_list);
		dwc3_gadget_ep_skip_trbs(dep, req);
		dwc3_gadget_giveback(dep, req, -ECONNRESET);
		request_count++;
@@ -1851,8 +1851,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
			/* If ep isn't started, then there's no end transfer
			 * pending
			 */
			if ((dep->flags & DWC3_EP_TRANSFER_STARTED) &&
				!(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
			if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
				dwc3_gadget_ep_cleanup_cancelled_requests(dep);

			goto out;
@@ -3583,11 +3582,8 @@ int dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt)
	ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params);
	WARN_ON_ONCE(ret);
	dep->resource_index = 0;
	if (ret == -ETIMEDOUT) {
		dbg_log_string("%s(%d): endxfer ret:%d",
				dep->name, dep->number, ret);
		return ret;
	}

	dbg_log_string("%s(%d): endxfer ret:%d", dep->name, dep->number, ret);

	if (!interrupt)
		dep->flags &= ~DWC3_EP_TRANSFER_STARTED;