Hi,

On 12/26/2016 04:01 PM, Baolin Wang wrote:
> On some platfroms(like x86 platform), when one core is running the USB gadget
> irq thread handler by dwc3_thread_interrupt(), meanwhile another core also can
> respond other interrupts from dwc3 controller and modify the event buffer by
> dwc3_interrupt() function, that will cause getting the wrong event count in
> irq thread handler to make the USB function abnormal.
>
> We should add spin_lock/unlock() in dwc3_check_event_buf() to avoid this race.

Why not spin_lock_irq ones? This lock seems to be used in both
normal and interrupt threads. Or, I missed anything?

Best regards,
Lu Baolu

>
> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
> ---
>  drivers/usb/dwc3/gadget.c |    6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 6785595..1a1e1f4 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -2894,10 +2894,13 @@ static irqreturn_t dwc3_check_event_buf(struct 
> dwc3_event_buffer *evt)
>               return IRQ_HANDLED;
>       }
>  
> +     spin_lock(&dwc->lock);
>       count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
>       count &= DWC3_GEVNTCOUNT_MASK;
> -     if (!count)
> +     if (!count) {
> +             spin_unlock(&dwc->lock);
>               return IRQ_NONE;
> +     }
>  
>       evt->count = count;
>       evt->flags |= DWC3_EVENT_PENDING;
> @@ -2914,6 +2917,7 @@ static irqreturn_t dwc3_check_event_buf(struct 
> dwc3_event_buffer *evt)
>               memcpy(evt->cache, evt->buf, count - amount);
>  
>       dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count);
> +     spin_unlock(&dwc->lock);
>  
>       return IRQ_WAKE_THREAD;
>  }

Reply via email to