[PATCH 14/20] USB: EHCI: Fix isochronous URB leak

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

 



From: Karsten Wiese <fzuuzf@xxxxxxxxxxxxxx>

ehci-hcd uses usb_get_urb() and usb_put_urb() in an unbalanced way causing
isochronous URB's kref.counts incrementing once per usb_submit_urb() call.
The culprit is *usb being set to NULL when usb_put_urb() is called after URB
is given back.
Due to other fixes there is no need for ehci-hcd to deal with usb_get_urb()
nor usb_put_urb() anymore, so patch removes their usages in ehci-hcd.
Patch also makes ehci_to_hcd(ehci)->self.bandwidth_allocated adjust, if a
stream finishes.

Signed-off-by: Karsten Wiese <fzu@xxxxxxxxxxxxxxxxxxxxx>
Cc: David Brownell <david-b@xxxxxxxxxxx>
Cc: stable <stable@xxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>
---
 drivers/usb/host/ehci-sched.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 07bcb93..1d0b49e 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1536,7 +1536,7 @@ itd_link_urb (
 					struct ehci_itd, itd_list);
 			list_move_tail (&itd->itd_list, &stream->td_list);
 			itd->stream = iso_stream_get (stream);
-			itd->urb = usb_get_urb (urb);
+			itd->urb = urb;
 			itd_init (ehci, stream, itd);
 		}
 
@@ -1645,7 +1645,7 @@ itd_complete (
 	(void) disable_periodic(ehci);
 	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
 
-	if (unlikely (list_empty (&stream->td_list))) {
+	if (unlikely(list_is_singular(&stream->td_list))) {
 		ehci_to_hcd(ehci)->self.bandwidth_allocated
 				-= stream->bandwidth;
 		ehci_vdbg (ehci,
@@ -1656,7 +1656,6 @@ itd_complete (
 	iso_stream_put (ehci, stream);
 
 done:
-	usb_put_urb(urb);
 	itd->urb = NULL;
 	if (ehci->clock_frame != itd->frame || itd->index[7] != -1) {
 		/* OK to recycle this ITD now. */
@@ -1949,7 +1948,7 @@ sitd_link_urb (
 				struct ehci_sitd, sitd_list);
 		list_move_tail (&sitd->sitd_list, &stream->td_list);
 		sitd->stream = iso_stream_get (stream);
-		sitd->urb = usb_get_urb (urb);
+		sitd->urb = urb;
 
 		sitd_patch(ehci, stream, sitd, sched, packet);
 		sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size,
@@ -2034,7 +2033,7 @@ sitd_complete (
 	(void) disable_periodic(ehci);
 	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
 
-	if (list_empty (&stream->td_list)) {
+	if (list_is_singular(&stream->td_list)) {
 		ehci_to_hcd(ehci)->self.bandwidth_allocated
 				-= stream->bandwidth;
 		ehci_vdbg (ehci,
@@ -2045,7 +2044,6 @@ sitd_complete (
 	iso_stream_put (ehci, stream);
 	/* OK to recycle this SITD now that its completion callback ran. */
 done:
-	usb_put_urb(urb);
 	sitd->urb = NULL;
 	sitd->stream = NULL;
 	list_move(&sitd->sitd_list, &stream->free_list);
-- 
1.6.0.2

--
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