This is a note to let you know that I've just added the patch titled USB: EHCI: simplify remainder computations to my gregkh-2.6 tree which can be found in directory form at: http://www.kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/patches/ and in git form at: git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/patches.git The filename of this patch is: usb-ehci-simplify-remainder-computations.patch The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.) If this patch meets the merge guidelines for a bugfix, it should be merged into Linus's tree before the next major kernel release. If not, it will be merged into Linus's tree during the next merge window. Either way, you will probably be copied on the patch when it gets sent to Linus for merging so that others can see what is happening in kernel development. If you have any questions about this process, please let me know. >From linux-usb-owner@xxxxxxxxxxxxxxx Thu Jul 22 15:51:42 2010 Date: Wed, 14 Jul 2010 11:03:36 -0400 (EDT) From: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> To: Greg KH <greg@xxxxxxxxx> cc: David Brownell <david-b@xxxxxxxxxxx>, USB list <linux-usb@xxxxxxxxxxxxxxx> Subject: USB: EHCI: simplify remainder computations Message-ID: <Pine.LNX.4.44L0.1007141055270.1634-100000@xxxxxxxxxxxxxxxxxxxx> This patch (as1406) adds a micro-optimization to ehci-hcd's scheduling code. Instead of computing remainders with respect to the schedule length, use bitwise-and (which is quicker). We know that the schedule length will always be a power of two, but the compiler doesn't have this information. Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> CC: David Brownell <david-b@xxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx> --- drivers/usb/host/ehci-sched.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1417,7 +1417,7 @@ iso_stream_schedule ( if (!stream->highspeed) period <<= 3; - now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; + now = ehci_readl(ehci, &ehci->regs->frame_index) & (mod - 1); /* Typical case: reuse current schedule, stream is still active. * Hopefully there are no gaps from the host falling behind @@ -1461,7 +1461,7 @@ iso_stream_schedule ( * jump until after the queue is primed. */ start = SCHEDULE_SLOP + (now & ~0x07); - start %= mod; + start &= mod - 1; stream->next_uframe = start; /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ @@ -1483,7 +1483,7 @@ iso_stream_schedule ( /* schedule it here if there's enough bandwidth */ if (enough_space) { - stream->next_uframe = start % mod; + stream->next_uframe = start & (mod - 1); goto ready; } } @@ -1599,7 +1599,7 @@ itd_link_urb ( struct ehci_iso_sched *iso_sched = urb->hcpriv; struct ehci_itd *itd; - next_uframe = stream->next_uframe % mod; + next_uframe = stream->next_uframe & (mod - 1); if (unlikely (list_empty(&stream->td_list))) { ehci_to_hcd(ehci)->self.bandwidth_allocated @@ -1637,13 +1637,13 @@ itd_link_urb ( next_uframe += stream->interval; stream->depth += stream->interval; - next_uframe %= mod; + next_uframe &= mod - 1; packet++; /* link completed itds into the schedule */ if (((next_uframe >> 3) != frame) || packet == urb->number_of_packets) { - itd_link (ehci, frame % ehci->periodic_size, itd); + itd_link(ehci, frame & (ehci->periodic_size - 1), itd); itd = NULL; } } @@ -2020,7 +2020,7 @@ sitd_link_urb ( "sched devp %s ep%d%s-iso [%d] %dms/%04x\n", urb->dev->devpath, stream->bEndpointAddress & 0x0f, (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out", - (next_uframe >> 3) % ehci->periodic_size, + (next_uframe >> 3) & (ehci->periodic_size - 1), stream->interval, hc32_to_cpu(ehci, stream->splits)); stream->start = jiffies; } @@ -2043,13 +2043,13 @@ sitd_link_urb ( sitd->urb = urb; sitd_patch(ehci, stream, sitd, sched, packet); - sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size, + sitd_link(ehci, (next_uframe >> 3) & (ehci->periodic_size - 1), sitd); next_uframe += stream->interval << 3; stream->depth += stream->interval << 3; } - stream->next_uframe = next_uframe % mod; + stream->next_uframe = next_uframe & (mod - 1); /* don't need that schedule data any more */ iso_sched_free (stream, sched); @@ -2258,7 +2258,7 @@ scan_periodic (struct ehci_hcd *ehci) now_uframe = ehci->next_uframe; if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { clock = ehci_readl(ehci, &ehci->regs->frame_index); - clock_frame = (clock >> 3) % ehci->periodic_size; + clock_frame = (clock >> 3) & (ehci->periodic_size - 1); } else { clock = now_uframe + mod - 1; clock_frame = -1; @@ -2267,7 +2267,7 @@ scan_periodic (struct ehci_hcd *ehci) free_cached_lists(ehci); ehci->clock_frame = clock_frame; } - clock %= mod; + clock &= mod - 1; clock_frame = clock >> 3; for (;;) { @@ -2356,7 +2356,7 @@ restart: * frame is current. */ if (((frame == clock_frame) || - (((frame + 1) % ehci->periodic_size) + (((frame + 1) & (ehci->periodic_size - 1)) == clock_frame)) && live && (q.sitd->hw_results & @@ -2423,7 +2423,8 @@ restart: || ehci->periodic_sched == 0) break; ehci->next_uframe = now_uframe; - now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; + now = ehci_readl(ehci, &ehci->regs->frame_index) & + (mod - 1); if (now_uframe == now) break; @@ -2436,7 +2437,7 @@ restart: } } else { now_uframe++; - now_uframe %= mod; + 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