diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2012-03-28 16:13:28 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-04-06 13:54:00 -0700 |
commit | da8bfb090c2b30af9f3879443355f7eb1d0fe10a (patch) | |
tree | 377d67c3c0cc1ad40d7357f821712c4c9ba6c639 /Documentation/usb/URB.txt | |
parent | bcf398537630bf20b4dbe59ba855b69f404c93cf (diff) |
USB documentation: explain lifetime rules for unlinking URBs
This patch (as1534c) updates the documentation for usb_unlink_urb and
related functions. It explains that the caller must prevent the URB
being unlinked from getting deallocated while the unlink is taking
place.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: Ming Lei <tom.leiming@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'Documentation/usb/URB.txt')
-rw-r--r-- | Documentation/usb/URB.txt | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/Documentation/usb/URB.txt b/Documentation/usb/URB.txt index 8ffce746d496..00d2c644068e 100644 --- a/Documentation/usb/URB.txt +++ b/Documentation/usb/URB.txt @@ -168,6 +168,28 @@ that if the completion handler or anyone else tries to resubmit it they will get a -EPERM error. Thus you can be sure that when usb_kill_urb() returns, the URB is totally idle. +There is a lifetime issue to consider. An URB may complete at any +time, and the completion handler may free the URB. If this happens +while usb_unlink_urb or usb_kill_urb is running, it will cause a +memory-access violation. The driver is responsible for avoiding this, +which often means some sort of lock will be needed to prevent the URB +from being deallocated while it is still in use. + +On the other hand, since usb_unlink_urb may end up calling the +completion handler, the handler must not take any lock that is held +when usb_unlink_urb is invoked. The general solution to this problem +is to increment the URB's reference count while holding the lock, then +drop the lock and call usb_unlink_urb or usb_kill_urb, and then +decrement the URB's reference count. You increment the reference +count by calling + + struct urb *usb_get_urb(struct urb *urb) + +(ignore the return value; it is the same as the argument) and +decrement the reference count by calling usb_free_urb. Of course, +none of this is necessary if there's no danger of the URB being freed +by the completion handler. + 1.7. What about the completion handler? |