[RFC 1/3] Keep track of givebacks in progress

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

 



This first proposed patch for solving the isochronous stream problem 
adds a mechanism for seeing whether or not an URB is currently being 
given back for a particular endpoint.

The mechanism isn't perfect.  It doesn't use any synchronization, so
it's possible that a CPU may think a giveback is still in progress even
after it has finished.  This shouldn't matter.  If an isochronous queue
empties out and then the driver starts a new stream within a few
milliseconds -- quickly enough that the change to giveback_in_progress
hasn't propagated to all the CPUs -- there won't be any harm in 
scheduling the new stream as a continuation of the old one.

Alan Stern


 drivers/usb/core/hcd.c |    3 +++
 include/linux/usb.h    |    5 +++--
 2 files changed, 6 insertions(+), 2 deletions(-)

Index: usb-3.11/include/linux/usb.h
===================================================================
--- usb-3.11.orig/include/linux/usb.h
+++ usb-3.11/include/linux/usb.h
@@ -68,9 +68,10 @@ struct usb_host_endpoint {
 	void				*hcpriv;
 	struct ep_device		*ep_dev;	/* For sysfs info */
 
-	unsigned char *extra;   /* Extra descriptors */
-	int extralen;
-	int enabled;
+	unsigned char			*extra;		/* Extra descriptors */
+	int				extralen;
+	int				enabled;
+	bool				giveback_in_progress;
 };
 
 /* host-side wrapper for one interface setting's parsed descriptors */
Index: usb-3.11/drivers/usb/core/hcd.c
===================================================================
--- usb-3.11.orig/drivers/usb/core/hcd.c
+++ usb-3.11/drivers/usb/core/hcd.c
@@ -1638,6 +1638,7 @@ int usb_hcd_unlink_urb (struct urb *urb,
 static void __usb_hcd_giveback_urb(struct urb *urb)
 {
 	struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus);
+	struct usb_host_endpoint *ep = urb->ep;
 	int status = urb->unlinked;
 	unsigned long flags;
 
@@ -1653,6 +1654,7 @@ static void __usb_hcd_giveback_urb(struc
 
 	/* pass ownership to the completion handler */
 	urb->status = status;
+	ep->giveback_in_progress = true;
 
 	/*
 	 * We disable local IRQs here avoid possible deadlock because
@@ -1668,6 +1670,7 @@ static void __usb_hcd_giveback_urb(struc
 	urb->complete(urb);
 	local_irq_restore(flags);
 
+	ep->giveback_in_progress = false;
 	atomic_dec(&urb->use_count);
 	if (unlikely(atomic_read(&urb->reject)))
 		wake_up(&usb_kill_urb_queue);


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