From: Michal Pecio <michal.pecio@gmail.com>
To: Mathias Nyman <mathias.nyman@intel.com>
Cc: linux-usb@vger.kernel.org
Subject: [PATCH 4/9] usb: xhci: Expedite processing missed isoch TDs on modern HCs
Date: Tue, 27 Aug 2024 19:50:53 +0200 [thread overview]
Message-ID: <20240827195053.185f5a91@foxbook> (raw)
In-Reply-To: <20240827194625.61be5733@foxbook>
xHCI spec rev. 1.0 allowed the TRB pointer of Missed Service events
to be NULL. In such case we have no idea which queued TD were missed
and which are still waiting for execution (and the spec forbids us
guessing based on frame numbers), so all we can do is set a flag on
the endpoint and wait for a new event with a valid dequeue pointer.
But hosts are also allowed to give us pointer to the last missed TRB
and this became mandatory in spec rev. 1.1 and later.
Use this pointer, if available, to immediately skip all missed TDs.
This may be particularly helpful for applications which queue very
few URBs/TDs for the sake of lowest possible latency.
It also saves the day if the next event is an underrun/overrun and
we will not get a valid dequeue pointer with it. If we then saw the
skip flag, we would have no way of knowing how many TDs were missed
and how many were queued after the host encountered ring underrun.
Handle Missed Service Error events as "error mid TD", if applicable,
because rev. 1.0 spec excplicitly says so in notes to 4.10.3.2. The
notes are no longer present in later revs, but rules of 4.9.1 should
apply universally.
Note that handle_tx_event() can cope with a host reporting MSE on an
early TRB of a TD and then failing to signal the final TRB. However,
in such (hopefully rare) case latency is not improved by this patch.
Tested on ASMedia ASM3142. This USB 3.1 host gives valid pointers in
Missed Service events and the skipping loop works until it finds the
last missed TRB indicated by the host. Then the skip flag is cleared
and the TRB passed to process_isoc_td() like any other.
Tested on NEC and VIA VL805. These USB 3.0 hosts give NULL pointers
so the event handler sets the skip flag and returns, as expected.
Change inspired by a recent discussion about realtime USB audio.
Link: https://lore.kernel.org/linux-usb/76e1a191-020d-4a76-97f6-237f9bd0ede0@gmx.net/T/
Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
---
drivers/usb/host/xhci-ring.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index e65cc80cb285..cc0420021683 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2413,8 +2413,14 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
frame->status = -EOVERFLOW;
if (ep_trb != td->last_trb)
td->error_mid_td = true;
break;
+ case COMP_MISSED_SERVICE_ERROR:
+ frame->status = -EXDEV;
+ sum_trbs_for_length = true;
+ if (ep_trb != td->last_trb)
+ td->error_mid_td = true;
+ break;
case COMP_INCOMPATIBLE_DEVICE_ERROR:
case COMP_STALL_ERROR:
frame->status = -EPROTO;
break;
@@ -2730,13 +2736,17 @@ static int handle_tx_event(struct xhci_hcd *xhci,
* When encounter missed service error, one or more isoc tds
* may be missed by xHC.
* Set skip flag of the ep_ring; Complete the missed tds as
* short transfer when process the ep_ring next time.
+ * If the xHC tells us the last missed TRB (ep_trb_dma != NULL)
+ * perform the skipping right away.
*/
ep->skip = true;
xhci_dbg(xhci,
- "Miss service interval error for slot %u ep %u, set skip flag\n",
- slot_id, ep_index);
+ "Miss service interval error for slot %u ep %u, set skip flag, go ahead %d\n",
+ slot_id, ep_index, !!ep_trb_dma);
+ if (ep_trb_dma)
+ break;
return 0;
case COMP_NO_PING_RESPONSE_ERROR:
ep->skip = true;
xhci_dbg(xhci,
--
2.43.0
next prev parent reply other threads:[~2024-08-27 17:50 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-27 17:46 [PATCH 0/9] Various xhci fixes and improvements Michal Pecio
2024-08-27 17:47 ` [PATCH 1/9] usb: xhci: Fix double newline in a debug message Michal Pecio
2024-08-27 17:48 ` [PATCH 2/9] usb: xhci: Fix handling errors mid TD followed by other errors Michal Pecio
2024-08-27 17:49 ` [PATCH 3/9] usb: xhci: Clean up the TD skipping loop Michal Pecio
2024-08-27 17:50 ` Michal Pecio [this message]
2024-08-27 17:51 ` [PATCH 5/9] usb: xhci: Simplify error_mid_td marking Michal Pecio
2024-08-27 17:52 ` [PATCH 6/9] usb: xhci: Sanity check "spurious success" handling Michal Pecio
2024-08-27 17:53 ` [PATCH 7/9] usb: xhci: Don't lie about trb_comp_code in handle_tx_event() Michal Pecio
2024-08-27 17:54 ` [PATCH 8/9] usb: xhci: Print completion code in the empty ring warning Michal Pecio
2024-08-27 17:55 ` [PATCH 9/9] usb: xhci: Clean up and rename bad stream event handler Michal Pecio
2024-08-28 10:21 ` [PATCH 0/9] Various xhci fixes and improvements FPS
2024-08-28 13:24 ` Michał Pecio
2024-08-28 13:48 ` fps
2024-08-28 11:14 ` Mathias Nyman
2024-08-28 15:02 ` Michał Pecio
2024-08-30 11:53 ` Michał Pecio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240827195053.185f5a91@foxbook \
--to=michal.pecio@gmail.com \
--cc=linux-usb@vger.kernel.org \
--cc=mathias.nyman@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).