On Fri, 8 Nov 2013, Sebastian Andrzej Siewior wrote:

> On 03.07.13, Ming Lei wrote:
...
> > +   /*
> > +    * 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);
> 
> How can there be a dead lock if you always complete in the same context
> (either BH or hardirq) for a given device [0]?

A lock will often be acquired in more than one place.  For example, in
both an URB completion handler and a timer routine.

Suppose a driver does spin_lock_irq(&lock) in the timer handler, but
does spin_lock(&lock) in the completion handler, expecting that the
completion handler will always be called with interrupts disabled.  If
the completion handler now runs with interrupts enabled, this would
lead to deadlock if a timer interrupt occurs while the completion
handler is running.

> Why do you choose to complete in BH context instead using threaded irqs
> and complete in the thread?

This has been discussed a few times already in the mailing list.  
Briefly, measurements showed noticeably decreased throughput for USB
mass storage transfers using threaded IRQs, compared to the BH
implementation.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to