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

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

 



On Mon, Sep 26, 2011 at 05:41:02PM +0800, Andiry Xu wrote:
> Hi Sarah,
> 
> This is the patchset for xHCI dynamic ring expansion.
> 
> When room_on_ring() check fails, try to expand the ring with double segment
> numbers. It's achieved by either finding a cached ring or allocating a new
> ring with the same number of sgements as the old ring, then link the old ring
> to the new ring. It fixes the "ERROR: no room on ring" error unless the
> driver askes for a ring with more than 256 segments.

I don't think this patchset is sufficient (and there's a couple bugs as
well).  If you're only checking whether you run out of space when
room_on_ring fails, then it's pretty trivial to work the driver into a
situation where it can't expand the rings.

For example, say you have a one-segment ring, and someone queues a 3-TRB
TD, which completes.  Then they try to queue two 61-TRB TDs in a row.
For the first one, room_on_ring() succeeds, the TD is queued, and the
link TRB at the end of the segment is given to the hardware (the
ownership bit is toggled).  Then room_on_ring() fails for the second TD.

The driver can't overwrite the link TRB that it just gave to the
hardware (details for why is in my response to patch 3), so unless it
adds a link TRB to a new segment in the middle of the ring, it can't
expand the ring and must fail that particular transfer.  But later
transfers could succeed after the second TD completes and you can
successfully expand the ring.  That will play havoc with applications
that submit big transfers.

What I'd like to see a ring expansion patchset do is this:

1. Modify the ring handling code to keep track of how many TRBs are
actually queued to the ring.  This will help us not *walk the ring*
every time we need to queue a transfer, which is a time-waster for
larger transfers.  The tricky bit will be handling updates to that
queued TRB number when a Set TR Dequeue Pointer command completes.

2. Before giving control of a link TRB to the hardware, check if the
number of queued TRBs is greater than half the capacity of the ring.  If
so, preemptively double the ring, adding the new segments in between the
current enqueue segment and the next segment.  If we know the current TD
to be queued requires more ring segments than a doubled-in-size ring
would hold, allocate as many segments as that transfer needs (maybe
adding one more segment for good measure).

What do you think?  I'm open to other suggestions, but I really think we
need to pre-emptively expand the ring, rather than waiting for
room_on_ring to fail.

Sarah Sharp

> It's tested with an isoc device which requires at least 32 segments.
> The patchset is based on AMD isoc link TRB quirk patch.
> 
> Thanks,
> Andiry
> 
> ---
> 
> Andiry Xu (3):
>   xHCI: store ring's last segment and segment numbers
>   xHCI: set cycle state when allocate rings
>   xHCI: dynamic ring expansion
> 
>  drivers/usb/host/xhci-mem.c  |  132 +++++++++++++++++++++++++++++++++++-------
>  drivers/usb/host/xhci-ring.c |   38 +++++++++----
>  drivers/usb/host/xhci.h      |    5 ++
>  3 files changed, 142 insertions(+), 33 deletions(-)
> 
> -- 
> 1.7.4.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