Re: [PATCH 3/3] xHCI: dynamic ring expansion

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

 



On Tue, Sep 27, 2011 at 01:00:44PM +0800, Andiry Xu wrote:
> On Mon, 2011-09-26 at 09:00 -0700, Sarah Sharp wrote:
> > On Mon, Sep 26, 2011 at 05:41:05PM +0800, Andiry Xu wrote:
> When expand a ring, I try to use a cached ring first; if a suitable
> cached ring is available, the ring structure needs to be freed anyway.
> If I need to allocate new segments, use xhci_ring_alloc() is simple and
> makes the code look cleaner, I don't need to call segment alloc and link
> functions directly.
> 
> Maybe factor out the segment allocation and linking part in
> xhci_ring_alloc() as a single function is a good idea, so you do not
> need to duplicate the code.

Yeah, refactoring out the segment allocation and linking would probably
be better than calling xhci_ring_alloc and then freeing the xhci_ring
structure.

> > At that point, you've given control the link TRB to the hardware by
> > toggling the cycle bit.  If you try to overwrite a link TRB that's given
> > over to the hardware, one of two things will happen:
> > 
> > 1. The hardware has already cached the link TRB, and the write will
> > never be noticed.  It will just go back to the top of the original
> > segment after processing TD A, TRB 3.  But adding that new segment won't help
> > you enqueue TD B.
> > 
> > 2. The hardware hasn't cached the link TRB and it will go fetch TRBs in
> > the new segment.  If the new segments have the cycle bit set to software
> > owned (which I think you do that in this patch), then hardware will stop
> > on the first TRB of the new segment (since it doesn't own that TRB) and
> > fail to execute the rest of TD A.  Then the cancellation code will run,
> > and goodness knows what it will make of the ring structure and where the
> > hardware thinks it is stopped.
> > 
> 
> Oh, I see your point. Yes, you are right; I failed to realize this
> scenario. So we can not expand a ring if "the software has toggled the
> cycle while the hardware has not", right? If that's the case, preemptive
> ring expansion is necessary.

Only software toggles the cycle bit.  The hardware dequeue pointer is
tracked by what events are placed on the event ring; it doesn't touch
the cycle bit for rings where it is the consumer.  So yes, preemptive
ring expansion is necessary. :)

> > So you can't just blindly assume you'll always be expanding the ring
> > before you wrap around the link TRB at the end of the segment.  I would
> > highly recommend you not pursue the option of adding link TRBs in the
> > middle of the segment, as none of the ring walking code, cancellation
> > code, or enqueuing code is set up to handle that.  Because adding link
> > TRBs in the middle would be such a radical change, I think you really
> > need pre-emptive ring expansion before overwriting link TRBs.
> > 
> 
> When you say "adding link TRBs in the middle of segment", do you mean
> adding link TRB not as the last the TRB of a segment, say, the 64th TRB?
> I don't think I have done that sort of things. 

Yes, that's what I mean.  And no, your patches don't do that.  It would
be an option to expand the rings, but I was pointing it out as one of
the tougher options to go with.

> > <snip>
> > > -	if (!room_on_ring(xhci, ep_ring, num_trbs)) {
> > > -		/* FIXME allocate more room */
> > > -		xhci_err(xhci, "ERROR no room on ep ring\n");
> > > -		return -ENOMEM;
> > > -	}
> > > +
> > > +	while (1) {
> > > +		if (room_on_ring(xhci, ep_ring, num_trbs))
> > > +			break;
> > > +
> > > +		if (ep_ring->num_segs >= 256) {
> > > +			xhci_err(xhci, "ERROR no room on ring "
> > > +						"after ring expansion\n");
> > > +			return -ENOMEM;
> > > +		}
> > 
> > Please don't place arbitrary limits on ring expansion like this.  I've
> > heard from at least one customer that they'll may need ring segments in the
> > thousands, so I've stopped assuming I know what ring size is "too big".
> > Just let the kernel run out of memory if drivers attempt to queue too
> > many big transfers.
> > 
> 
> Ah, I'm not aware of that. I thought 256 segments is already big enough
> for any transfer...

I thought so too (actually I thought 100 would be enough), but
apparently some devices need to queue a large number of very big bulk
transfers.  So let's not limit the size of a ring. :)

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