On Fri, 9 Apr 2004, Greg KH wrote:
> On Fri, Apr 09, 2004 at 11:24:44AM -0400, Alan Stern wrote:
> > Greg, what do you think? Should the core have a usb_wait_for_urb()
> > function that simply blocks until the URB's refcount goes back down to 1?
>
> I don't think it's necessary if a driver uses the usb_alloc_urb() and
> usb_free_urb() calls, right?
If the bluetooth driver had done that, it would not have experienced this
problem.
(There might still have been a related problem: rmmod might succeed in
unloading the driver from memory before all the completion handlers for
URBs-in-flight had run. Nobody has reported that problem to my knowledge.
Probably unmapping the code region will always take more than a few
milliseconds so it will never come up.)
> That being said:
>
> > Wasn't the whole point of the difference between them that asynchronous
> > usb_unlink_urb() guarantees only the first one whereas synchronous
> > usb_unlink_urb() tries to guarantee both? Unfortunately it only _tries_,
> > it doesn't _guarantee_.
>
> That's not ok. Synchronous usb_unlink_urb() really needs to work
> properly. No "tries", it must. Otherwise drivers have no idea if they
> can reuse the urb or not. That's not acceptable, and needs to get fixed
> as soon as possible.
This has been the heart of a long discussion between David and me. The
main points coming out of that discussion are:
1. Synchronous usb_unlink_urb() does work properly, in the sense
that it does what the kerneldoc says it will do.
2. Sometimes drivers need to know that an URB is available for
reuse, not just that it has been unlinked. Synchronous
unlinks are not the right way to do this, despite what people
may think (and despite the connotations of "synchronous").
3. Sometimes drivers need to know not that an URB is available
for deallocation (which won't matter if it uses usb_free_urb)
but rather that the completion handler has finished executing.
Again, synchronous unlinks are not the way to do this.
4. Most, but not all, of the time drivers need to know these things
only during their disconnect() routines. Most of the time
synchronous unlink returns with no error (in which case it does
what the driver needs) -- but that often fails during disconnect
when using UHCI!
5. Waiting for the URB's refcount to drop to 1 does accomplish the
tasks mentioned in (2) and (3), unless the driver has performed
some weird meddling with the count.
6. For many purposes, synchronous usb_unlink_urb could be replaced
by a combination of asynchronous unlink followed by wait_for_urb.
The two approaches differ when the completion handler resubmits
the URB: synchronous unlink will return after the handler runs
(if no errors crop up) whereas wait_for_urb will wait forever.
During disconnect this doesn't matter since the core guarantees
that no new URBs will be accepted for any endpoint in the
interface being unbound.
7. When the core calls a driver's disconnect() method, it guarantees
in addition that all in-flight URBs for endpoints in the
interface have been unlinked. However, it does _not_ guarantee
that those URBs have completed. Thanks to the presence of
disable_endpoint in the OHCI and EHCI drivers this happens as
a side-effect; it doesn't happen with the UHCI driver.
8. There are occasions other than disconnect when drivers do some
of these questionable things. Like the bluetooth hci_usb driver,
which shares code between its disconnect and device-close
handlers.
Plus maybe a few other things I can't remember right now. The whole thing
is kind of a mess. Ideally I would like to see synchronous unlink go away
entirely, to be replaced by async unlink, wait_for_urb, plus a simple
means of reliably preventing resubmission by completion handlers. Not an
easy thing to do, especially during a stable kernel series.
> So only uhci has this issue, right? Sounds like uhci need to implement
> the wait_for_urb() call internally to its driver to accomplish the
> synchronous unlink.
Well, as you can see it's a lot of interlocking issues, not just the lack
of some functionality in UHCI. While the lines of responsibility are
clearly drawn at the moment, not everyone feels they are drawn well. So
while this was definitely a bug in the bluetooth driver, one can argue
that the USB API should be changed to make the core do more of the work.
Until that change is made, however, we just have to keep in mind that
synchronous unlinks are liable to be sources of trouble.
Alan Stern
-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel