Skip to content

Commit 91edf5a

Browse files
Michal Peciogregkh
authored andcommitted
xhci: fix matching completion events with TDs
A trb_in_td() call is used to determine if a completion event matches any TRB of the currently executing TD. This function is told to start searching right after the last finished TD, which is not at all where the currently expected TD is guaranteed to begin, because some TDs in between may have been cancelled. Not only is a pointless work performed, but a bug resulting in the HC executing cancelled TDs was seen to trick the driver into associating events from a TD just cancelled with an unrelated future TD. Since the ring is being traversed for the specific purpose of finding a match with the current TD, always start from its first TRB. This is the most reliable bit of information that we posses. Tracking of HC's work progress is not affected, except for cases when a misattributed event would have moved dequeue past a pending TD. Signed-off-by: Michal Pecio <michal.pecio@gmail.com> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://lore.kernel.org/r/20240229141438.619372-7-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 2e8dd2d commit 91edf5a

File tree

1 file changed

+3
-4
lines changed

1 file changed

+3
-4
lines changed

drivers/usb/host/xhci-ring.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2813,7 +2813,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
28132813
td_num--;
28142814

28152815
/* Is this a TRB in the currently executing TD? */
2816-
ep_seg = trb_in_td(xhci, ep_ring->deq_seg, ep_ring->dequeue,
2816+
ep_seg = trb_in_td(xhci, td->start_seg, td->first_trb,
28172817
td->last_trb, ep_trb_dma, false);
28182818

28192819
/*
@@ -2881,9 +2881,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
28812881
"part of current TD ep_index %d "
28822882
"comp_code %u\n", ep_index,
28832883
trb_comp_code);
2884-
trb_in_td(xhci, ep_ring->deq_seg,
2885-
ep_ring->dequeue, td->last_trb,
2886-
ep_trb_dma, true);
2884+
trb_in_td(xhci, td->start_seg, td->first_trb,
2885+
td->last_trb, ep_trb_dma, true);
28872886
return -ESHUTDOWN;
28882887
}
28892888
}

0 commit comments

Comments
 (0)