Re: Problem when USB hub is inserted

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

 



On Sat, 14 Aug 2010, Alessio Sangalli wrote:

> On 08/13/2010 06:32 PM, Alan Stern wrote:
> 
> > The number of times the larger loop executes depends on how often a
> > periodic URB completes.  That might be hundreds of iterations, but if
> > it is then most of the iterations should be very fast.  For example, if
> > there's an isochronous URB with 10 packets and a period of 64 uframes,
> > then the loop would execute 640 times but only 10 of those iterations
> > would do any work.  This shouldn't take 2 milliseconds.
> 
> Ok but I only had a mouse connected here...
> 
> > Can you find out how much work is done on each loop iteration?  For
> > example, how many times does the "while (q.ptr != NULL) {" inner loop
> 
> I will experiment with the code.

I managed to lose track of this thread for a couple of months, sorry.

Here is a patch which ought to reduce the overhead of the loop.  It 
avoids doing the expensive call to qh_completions() more than once for 
each qh.

Alan Stern



Index: usb-2.6/drivers/usb/host/ehci.h
===================================================================
--- usb-2.6.orig/drivers/usb/host/ehci.h
+++ usb-2.6/drivers/usb/host/ehci.h
@@ -117,6 +117,7 @@ struct ehci_hcd {			/* one per controlle
 	struct timer_list	watchdog;
 	unsigned long		actions;
 	unsigned		stamp;
+	unsigned		periodic_stamp;
 	unsigned		random_frame;
 	unsigned long		next_statechange;
 	ktime_t			last_periodic_enable;
Index: usb-2.6/drivers/usb/host/ehci-q.c
===================================================================
--- usb-2.6.orig/drivers/usb/host/ehci-q.c
+++ usb-2.6/drivers/usb/host/ehci-q.c
@@ -838,6 +838,7 @@ qh_make (
 				is_input, 0,
 				hb_mult(maxp) * max_packet(maxp)));
 		qh->start = NO_FRAME;
+		qh->stamp = ehci->periodic_stamp;
 
 		if (urb->dev->speed == USB_SPEED_HIGH) {
 			qh->c_usecs = 0;
Index: usb-2.6/drivers/usb/host/ehci-sched.c
===================================================================
--- usb-2.6.orig/drivers/usb/host/ehci-sched.c
+++ usb-2.6/drivers/usb/host/ehci-sched.c
@@ -2261,6 +2261,7 @@ scan_periodic (struct ehci_hcd *ehci)
 	}
 	clock &= mod - 1;
 	clock_frame = clock >> 3;
+	++ehci->periodic_stamp;
 
 	for (;;) {
 		union ehci_shadow	q, *q_p;
@@ -2289,10 +2290,14 @@ restart:
 				temp.qh = qh_get (q.qh);
 				type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next);
 				q = q.qh->qh_next;
-				modified = qh_completions (ehci, temp.qh);
-				if (unlikely(list_empty(&temp.qh->qtd_list) ||
-						temp.qh->needs_rescan))
-					intr_deschedule (ehci, temp.qh);
+				if (temp.qh->stamp != ehci->periodic_stamp) {
+					modified = qh_completions(ehci, temp.qh);
+					if (!modified)
+						temp.qh->stamp = ehci->periodic_stamp;
+					if (unlikely(list_empty(&temp.qh->qtd_list) ||
+							temp.qh->needs_rescan))
+						intr_deschedule(ehci, temp.qh);
+				}
 				qh_put (temp.qh);
 				break;
 			case Q_TYPE_FSTN:
@@ -2427,6 +2432,7 @@ restart:
 				free_cached_lists(ehci);
 				ehci->clock_frame = clock_frame;
 			}
+			++ehci->periodic_stamp;
 		} else {
 			now_uframe++;
 			now_uframe &= mod - 1;

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