Re: [PATCH 2/2] ehci: Respect IST when scheduling new iTDs.

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

 



On Mon, 12 Oct 2009, Sarah Sharp wrote:

> On Sun, Oct 11, 2009 at 10:31:36AM -0400, Alan Stern wrote:
> 
> > Can you describe which hardware this applies to?  And does the bug
> > affect high-speed isochronous endpoints?
> 
> I don't know if I'm supposed to say which hardware this applies to, so
> I'll have to err on the side of caution.  The chipset engineers said
> this only applies to split isoc transactions, but I didn't tweak a high
> speed webcam driver to confirm.

You might want to make this change as specific as possible, so that 
existing controllers will see the same behavior as before.  That means 
testing for the bad controller type and testing for full-speed 
transfers.

> > On Fri, 9 Oct 2009, Sarah Sharp wrote:
> > 
> > > @@ -1354,6 +1354,7 @@ iso_stream_schedule (
> > >  		period <<= 3;
> > >  
> > >  	now = ehci_readl(ehci, &ehci->regs->frame_index) % mod;
> > > +	next = now + ehci->i_thresh;
> > >  
> > >  	/* when's the last uframe this urb could start? */
> > >  	max = now + mod;
> > > @@ -1365,13 +1366,15 @@ iso_stream_schedule (
> > >  	 */
> > >  	if (likely (!list_empty (&stream->td_list))) {
> > >  		start = stream->next_uframe;
> > > -		if (start < now)
> > > +		if (start < next)
> > >  			start += mod;
> > >  
> > >  		/* Fell behind (by up to twice the slop amount)? */
> > >  		if (start >= max - 2 * 8 * SCHEDULE_SLOP)
> > >  			start += period * DIV_ROUND_UP(
> > > -					max - start, period) - mod;
> > > +					max - start + ehci->i_thresh,
> > > +					period)
> > > +				- mod;
> > >  
> > >  		/* Tried to schedule too far into the future? */
> > >  		if (unlikely((start + sched->span) >= max)) {
> > >			status = -EFBIG;
> > >			goto fail;
> > >		}
> > >		stream->next_uframe = start;
> > >		goto ready;
> > 
> > Sorry, what I wrote before wasn't quite right.
> 
> Can you give an example of where my patch would fail to schedule
> correctly?  start does need to be moded by the periodic schedule size
> before we jump to ready, but was there a different mistake in this
> patch?

Let's see.  For the sake of argument, suppose mod is 1024 and
ehci->i_thresh is 10 (frame caching).  Consider the case where now is
1020, max is 2044, next is 1030, and stream->next_uframe is 3.  Since
the (start < next) test succeeds, you'll change start to 1027.  Then 
the (start >= max - 2 * 8 * SCHEDULE_SLOP) test will fail, as will 
the (start + sched->span >= max) test.  So you'll set 
stream->next_uframe to (start % mod) == 3 and end up scheduling in the 
middle of the threshold period, which wraps around from 1020 to 6.

> > This computation is 
> > tricky.  To check whether start is too small, you have to fit it into 
> > the interval from next to (next + mod - 1).  But then to check whether 
> > it is too big, you have to fit it into the interval from now to (now + 
> > mod - 1).  And then in the end, you need to assign stream->next_uframe 
> > a value between 0 and (mod - 1).
> > 
> > Since mod is always a power of two, the easiest approach may be 
> > something like this:
> > 
> > 	next = now + ehci->i_thread;
> > 		...
> > 		start = stream->next_uframe;
> > 
> > 		/* Fell behind (by up to twice the slop amount)? */
> > 		if ((start - next) & (mod - 1) >=
> > 				mod - 2 * 8 * SCHEDULE_SLOP)
> > 			start += period * DIV_ROUND_UP(
> > 					(next - start) & (mod - 1),
> > 					period);
> 
> This looks fine, except in the case where the driver has scheduled
> transfers really far in the future (where stream->next_uframe > next +
> mod - 2 * 8 * SCHEDULE_SLOP).  The old code and my patch have a similar
> problem, of course.

You can fix that by changing the test below; replace max by (max - 2 *
8 * SCHEDULE_SLOP) or something of the sort.

> > 		/* Tried to schedule too far into the future? */
> > 		if (unlikely(((start - now) & (mod - 1)) + sched->span
> > 				>= max)) { ...
> > 		}
> > 		stream->next_uframe = start % mod;
> > 		goto ready;
> 
> I agree with this math.

I agree with your agreement.  :-)

Alan Stern

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