Re: [PATCH v2] usb: core: remove local_irq_save/restore around urb->complete

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Oct 04, 2016 at 02:50:09PM -0400, Alan Stern wrote:
> On Tue, 4 Oct 2016, Bin Liu wrote:
> 
> > local_irq_save() disables irq completely on non-SMP which causes the
> > hard interrupt handler unable to serve interrupts, which loses the
> > benefit that the giveback tasklet brings in usb_hcd_giveback_urb().
> 
> It doesn't lose all the benefit.  Interrupts are still enabled before 
> and after the local_irq_save region.

Yeah, but the problem is the irq disabled region is sometimes huge (in
ms range in uvc device driver).
> 
> > One example of the issues caused by this disabling local irq is that
> > urb->complete in uvc driver takes about 1ms, which holds the host
> > controller to not receive packets for so long that causes webcam drops
> > data.
> > 
> > I don't see any callers of usb_hcd_giveback_urb() holding a spin_lock,
> > so it is safe to remove this local_irq_save/restore() around
> > urb->complete.
> 
> How carefully did you look?  ehci_urb_done() holds ehci->lock while 
> calling usb_hcd_giveback_urb().

Obviously not much :( I checked a few level up from ehci_urb_done(), but
didn't reach echi->lock...

> 
> Anyway, that's not the problem this code was meant to solve.  The 
> problem is that the completion routine in a USB driver might expect to 
> be called with interrupts disabled, and therefore might use spin_lock() 
> instead of spin_lock_irqsave().  You can't remove this local_irq_save() 
> until you have checked all the completion routines in all the USB 
> drivers to make sure they don't make this mistake.

Ok, I will try to understand it more. Thanks for the comments.

Regards,
-Bin.

> 
> Alan Stern
> 
> > Signed-off-by: Bin Liu <b-liu@xxxxxx>
> > ---
> > v2: fix build warning
> > 
> >  drivers/usb/core/hcd.c | 14 --------------
> >  1 file changed, 14 deletions(-)
> > 
> > diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
> > index 479e223..c18d480 100644
> > --- a/drivers/usb/core/hcd.c
> > +++ b/drivers/usb/core/hcd.c
> > @@ -1733,7 +1733,6 @@ static void __usb_hcd_giveback_urb(struct urb *urb)
> >  	struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus);
> >  	struct usb_anchor *anchor = urb->anchor;
> >  	int status = urb->unlinked;
> > -	unsigned long flags;
> >  
> >  	urb->hcpriv = NULL;
> >  	if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
> > @@ -1751,20 +1750,7 @@ static void __usb_hcd_giveback_urb(struct urb *urb)
> >  	/* pass ownership to the completion handler */
> >  	urb->status = status;
> >  
> > -	/*
> > -	 * We disable local IRQs here avoid possible deadlock because
> > -	 * drivers may call spin_lock() to hold lock which might be
> > -	 * acquired in one hard interrupt handler.
> > -	 *
> > -	 * The local_irq_save()/local_irq_restore() around complete()
> > -	 * will be removed if current USB drivers have been cleaned up
> > -	 * and no one may trigger the above deadlock situation when
> > -	 * running complete() in tasklet.
> > -	 */
> > -	local_irq_save(flags);
> >  	urb->complete(urb);
> > -	local_irq_restore(flags);
> > -
> >  	usb_anchor_resume_wakeups(anchor);
> >  	atomic_dec(&urb->use_count);
> >  	if (unlikely(atomic_read(&urb->reject)))
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux