Commit a393a807 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

USB: EHCI: start new isochronous streams ASAP

This patch changes the initial delay before the startup of a newly
scheduled isochronous stream.  Currently the stream doesn't start
for at least 5 ms (40 microframes).  This value is just an estimate;
it has no real justification.

Instead, we can start the stream as soon as possible after the
scheduling computations are complete.  Essentially this requires
nothing more than reading the frame counter after the stream is
scheduled, instead of before.
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b35c5009
...@@ -1491,8 +1491,6 @@ sitd_slot_ok ( ...@@ -1491,8 +1491,6 @@ sitd_slot_ok (
* given EHCI_TUNE_FLS and the slop). Or, write a smarter scheduler! * given EHCI_TUNE_FLS and the slop). Or, write a smarter scheduler!
*/ */
#define SCHEDULING_DELAY 40 /* microframes */
static int static int
iso_stream_schedule ( iso_stream_schedule (
struct ehci_hcd *ehci, struct ehci_hcd *ehci,
...@@ -1506,27 +1504,13 @@ iso_stream_schedule ( ...@@ -1506,27 +1504,13 @@ iso_stream_schedule (
unsigned mod = ehci->periodic_size << 3; unsigned mod = ehci->periodic_size << 3;
struct ehci_iso_sched *sched = urb->hcpriv; struct ehci_iso_sched *sched = urb->hcpriv;
bool empty = list_empty(&stream->td_list); bool empty = list_empty(&stream->td_list);
bool new_stream = false;
period = stream->uperiod; period = stream->uperiod;
span = sched->span; span = sched->span;
if (!stream->highspeed) if (!stream->highspeed)
span <<= 3; span <<= 3;
now = ehci_read_frame_index(ehci) & (mod - 1);
/* Take the isochronous scheduling threshold into account */
if (ehci->i_thresh)
next = now + ehci->i_thresh; /* uframe cache */
else
next = (now + 2 + 7) & ~0x07; /* full frame cache */
/*
* Use ehci->last_iso_frame as the base. There can't be any
* TDs scheduled for earlier than that.
*/
base = ehci->last_iso_frame << 3;
next = (next - base) & (mod - 1);
/* Start a new isochronous stream? */ /* Start a new isochronous stream? */
if (unlikely(empty && !hcd_periodic_completion_in_progress( if (unlikely(empty && !hcd_periodic_completion_in_progress(
ehci_to_hcd(ehci), urb->ep))) { ehci_to_hcd(ehci), urb->ep))) {
...@@ -1542,7 +1526,7 @@ iso_stream_schedule ( ...@@ -1542,7 +1526,7 @@ iso_stream_schedule (
} }
compute_tt_budget(ehci->tt_budget, tt); compute_tt_budget(ehci->tt_budget, tt);
start = (now & ~0x07) + SCHEDULING_DELAY; start = ((-(++ehci->random_frame)) << 3) & (period - 1);
/* find a uframe slot with enough bandwidth. /* find a uframe slot with enough bandwidth.
* Early uframes are more precious because full-speed * Early uframes are more precious because full-speed
...@@ -1585,17 +1569,35 @@ iso_stream_schedule ( ...@@ -1585,17 +1569,35 @@ iso_stream_schedule (
start = (stream->ps.phase << 3) + stream->ps.phase_uf; start = (stream->ps.phase << 3) + stream->ps.phase_uf;
} }
start = (start - base) & (mod - 1); stream->next_uframe = start;
goto use_start; new_stream = true;
} }
now = ehci_read_frame_index(ehci) & (mod - 1);
/* Take the isochronous scheduling threshold into account */
if (ehci->i_thresh)
next = now + ehci->i_thresh; /* uframe cache */
else
next = (now + 2 + 7) & ~0x07; /* full frame cache */
/*
* Use ehci->last_iso_frame as the base. There can't be any
* TDs scheduled for earlier than that.
*/
base = ehci->last_iso_frame << 3;
next = (next - base) & (mod - 1);
start = (stream->next_uframe - base) & (mod - 1);
if (unlikely(new_stream))
goto do_ASAP;
/* /*
* Typical case: reuse current schedule, stream may still be active. * Typical case: reuse current schedule, stream may still be active.
* Hopefully there are no gaps from the host falling behind * Hopefully there are no gaps from the host falling behind
* (irq delays etc). If there are, the behavior depends on * (irq delays etc). If there are, the behavior depends on
* whether URB_ISO_ASAP is set. * whether URB_ISO_ASAP is set.
*/ */
start = (stream->next_uframe - base) & (mod - 1);
now2 = (now - base) & (mod - 1); now2 = (now - base) & (mod - 1);
/* Is the schedule already full? */ /* Is the schedule already full? */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment