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

Commit f4e921e6 authored by Arumuga Durai A's avatar Arumuga Durai A
Browse files

USB: dwc3: Fix spinlock recursion



As dwc3-interrupt() handles the interrupts on usb irq runs
in threaded context, which acquires the spin_lock without
disable local irq. When interrupt for transfer completion
event comes on the same CPU for the data transfer queued
to dwc3 by gsmd_start_rx() reacquires the lock results
in spinlock recursion. Fix this by changing
spin_lock/unlock() to spin_lock_irqsave/unlock_irqrestore().

CRs-Fixed: 1088909
Change-Id: I34b1ba5af355bf8d7919aac5ff248d8edaa89c22
Signed-off-by: default avatarArumuga Durai A <cadurai@codeaurora.org>
parent e5c91c68
Loading
Loading
Loading
Loading
+4 −3
Original line number Original line Diff line number Diff line
@@ -3592,16 +3592,17 @@ irqreturn_t dwc3_interrupt(int irq, void *_dwc)
	int				i;
	int				i;
	irqreturn_t			ret = IRQ_NONE;
	irqreturn_t			ret = IRQ_NONE;
	unsigned			temp_cnt = 0;
	unsigned			temp_cnt = 0;
	unsigned long			flags;
	ktime_t				start_time;
	ktime_t				start_time;


	start_time = ktime_get();
	start_time = ktime_get();
	spin_lock(&dwc->lock);
	spin_lock_irqsave(&dwc->lock, flags);


	dwc->irq_cnt++;
	dwc->irq_cnt++;


	if (dwc->err_evt_seen) {
	if (dwc->err_evt_seen) {
		/* controller reset is still pending */
		/* controller reset is still pending */
		spin_unlock(&dwc->lock);
		spin_unlock_irqrestore(&dwc->lock, flags);
		return IRQ_HANDLED;
		return IRQ_HANDLED;
	}
	}


@@ -3615,7 +3616,7 @@ irqreturn_t dwc3_interrupt(int irq, void *_dwc)
		temp_cnt += dwc->ev_buffs[i]->count;
		temp_cnt += dwc->ev_buffs[i]->count;
	}
	}


	spin_unlock(&dwc->lock);
	spin_unlock_irqrestore(&dwc->lock, flags);


	dwc->irq_start_time[dwc->irq_dbg_index] = start_time;
	dwc->irq_start_time[dwc->irq_dbg_index] = start_time;
	dwc->irq_completion_time[dwc->irq_dbg_index] =
	dwc->irq_completion_time[dwc->irq_dbg_index] =