Re: [PATCH 3.14-stable] usb: xhci: Prefer endpoint context dequeue pointer over stopped_trb

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

 



On Fri, 2014-05-02 at 13:18 -0700, Julius Werner wrote:
> commit 1f81b6d22a5980955b01e08cf27fb745dc9b686f upstream.
> 
> We have observed a rare cycle state desync bug after Set TR Dequeue
> Pointer commands on Intel LynxPoint xHCs (resulting in an endpoint that
> doesn't fetch new TRBs and thus an unresponsive USB device). It always
> triggers when a previous Set TR Dequeue Pointer command has set the
> pointer to the final Link TRB of a segment, and then another URB gets
> enqueued and cancelled again before it can be completed. Further
> investigation showed that the xHC had returned the Link TRB in the TRB
> Pointer field of the Transfer Event (CC == Stopped -- Length Invalid),
> but when xhci_find_new_dequeue_state() later accesses the Endpoint
> Context's TR Dequeue Pointer field it is set to the first TRB of the
> next segment.
> 
> The driver expects those two values to be the same in this situation,
> and uses the cycle state of the latter together with the address of the
> former. This should be fine according to the XHCI specification, since
> the endpoint ring should be stopped when returning the Transfer Event
> and thus should not advance over the Link TRB before it gets restarted.
> However, real-world XHCI implementations apparently don't really care
> that much about these details, so the driver should follow a more
> defensive approach to try to work around HC spec violations.
> 
> This patch removes the stopped_trb variable that had been used to store
> the TRB Pointer from the last Transfer Event of a stopped TRB. Instead,
> xhci_find_new_dequeue_state() now relies only on the Endpoint Context,
> requiring a small amount of additional processing to find the virtual
> address corresponding to the TR Dequeue Pointer. Some other parts of the
> function were slightly rearranged to better fit into this model.
> 
> This patch should be backported to kernels as old as 2.6.31 that contain
> the commit ae636747146ea97efa18e04576acd3416e2514f5 "USB: xhci: URB
> cancellation support."
> 
> [jwerner@xxxxxxxxxxxx: port back to code without correct stream handling]
> Signed-off-by: Julius Werner <jwerner@xxxxxxxxxxxx>
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx>
> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
> ---
>  drivers/usb/host/xhci-ring.c | 67 ++++++++++++++++++++------------------------
>  drivers/usb/host/xhci.c      |  1 -
>  drivers/usb/host/xhci.h      |  2 --
>  3 files changed, 31 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
> index 0ed64eb..dff9b5e 100644
> --- a/drivers/usb/host/xhci-ring.c
> +++ b/drivers/usb/host/xhci-ring.c
> @@ -550,6 +550,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
>  	struct xhci_generic_trb *trb;
>  	struct xhci_ep_ctx *ep_ctx;
>  	dma_addr_t addr;
> +	u64 hw_dequeue;
>  
>  	ep_ring = xhci_triad_to_transfer_ring(xhci, slot_id,
>  			ep_index, stream_id);
> @@ -559,56 +560,57 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
>  				stream_id);
>  		return;
>  	}
> -	state->new_cycle_state = 0;
> -	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
> -			"Finding segment containing stopped TRB.");
> -	state->new_deq_seg = find_trb_seg(cur_td->start_seg,
> -			dev->eps[ep_index].stopped_trb,
> -			&state->new_cycle_state);
> -	if (!state->new_deq_seg) {
> -		WARN_ON(1);
> -		return;
> -	}
>  
>  	/* Dig out the cycle state saved by the xHC during the stop ep cmd */
>  	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
>  			"Finding endpoint context");
>  	ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
> -	state->new_cycle_state = 0x1 & le64_to_cpu(ep_ctx->deq);
> +	hw_dequeue = le64_to_cpu(ep_ctx->deq);
[...]

Should we not pick commit c4bedb77ec4cb42f37cae4cbfddda8283161f7c8
('xhci: For streams the css flag most be read from the stream-ctx on ep
stop') before this?

Ben.

-- 
Ben Hutchings
Everything should be made as simple as possible, but not simpler.
                                                           - Albert Einstein

Attachment: signature.asc
Description: This is a digitally signed message part


[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]