On Tue, 10 Feb 2004, Stephen Hemminger wrote:

> Okay, I will try your patch.
> 
> I believe, but can't prove the race occurs when:
> CPU 0                                 CPU 1
> ------------------------------------------------------------------------------
> Uhci_irq                              Uhci_dequeue
> delete urb from uhci->urb_list
> put on complete_list
>                                       delete urb
>                                       put it on remove list
> 
> Then same urb get's processed twice, once on the complete
> list and once on the remove list.
> 
> An alternative solution would be to grab complete_list_lock
> in uhci_dequeue.

This sequence of events is supposed to be prevented by urb->lock.  The 
things you have listed under uhci_irq() run while holding that lock, and 
they won't occur at all if urb->status != -EINPROGRESS (see the 
beginning of uhci_transfer_result).

Meanwhile uhci_dequeue() is called from hcd_unlink_urb() in 
drivers/usb/core/hcd.c, which also acquires urb->lock and also won't do 
anything if urb->status != -EINPROGRESS.  It changes urb->status to either 
-ENOENT or -ECONNRESET.  The same thing happens in hcd_endpoint_disable(), 
except that urb->status is set to -ESHUTDOWN.

The problem is that uhci_transfer_result() doesn't change urb->status; it 
changes urbp->status instead.  That's the bug my patch fixes, and once it 
has been fixed the race you outlined can't occur.

Alan Stern



-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to