Skip to contentSkip to conversation

usb: octeon-hcd: keep SOF interrupts while a periodic pipe is due

PATCH Superseded Orgad Shaneh 2 participants 3 messages Sep 15 – Oct 11 USB

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 usb: octeon-hcd: keep SOF interrupts while a periodic pipe is due

cvmx_usb_schedule() now sleeps on an hrtimer until the nearest future periodic deadline instead of counting frames down on every SOF. The scan that finds that deadline only looks at pipes with

	next_tx_frame > usb->frame_number

which is right for picking the deadline, but it means a periodic pipe that is already due and was *not* started is invisible to the decision. A pipe can be due and not started for reasons that resolve on their own:
no idle hardware channel this round, its split window is closed (cvmx_usb_find_ready_pipe() rejects both), or another pipe owns usb->active_split.

Such a pipe is only retried from a SOF - cvmx_usb_next_pipe() looks at the isochronous and interrupt lists only when is_sof is true - so when some other periodic pipe sets a far deadline, the driver masks SOF, arms the timer for that far deadline and the due pipe waits for it. With a hub's status pipe as the far one, that is hundreds of frames; the code allows up to 8000 (one second) before it falls back to SOF.

Before the hrtimer this could not happen: any pipe with a future deadline set need_sof, so SOF stayed enabled every frame and the due pipe was retried on the next one.

Note the pipe that is due and not started, and keep SOF enabled in that case, exactly as the old code did. Nothing changes when no periodic pipe is due, which is the case the timer was added for.

Control and bulk pipes are excluded deliberately: their next_tx_frame is not updated on completion, so they are almost always "due" and would keep SOF enabled permanently.

Fixes aebbc7d63407 ("usb: octeon-hcd: sleep on an hrtimer for far-off periodic transfers")
Assisted-by Claude:claude-opus-5

---

drivers/usb/host/octeon-hcd.c +15 -3
@@ -1923,6 +1923,7 @@ static void cvmx_usb_schedule(struct octeon_hcd *usb, int is_sof)
 	struct cvmx_usb_pipe *pipe;
 	int need_sof;
 	u64 min_due;
+	bool due_now;
 	enum cvmx_usb_transfer ttype;
 
 	if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
@@ -1964,12 +1965,23 @@ done:
 	 */
 	need_sof = 0;
 	min_due = ~0ull;
+	due_now = false;
 	for (ttype = CVMX_USB_TRANSFER_CONTROL;
 	     ttype <= CVMX_USB_TRANSFER_INTERRUPT; ttype++) {
 		list_for_each_entry(pipe, &usb->active_pipes[ttype], node) {
-			if (pipe->next_tx_frame > usb->frame_number &&
-			    pipe->next_tx_frame < min_due)
+			if (pipe->next_tx_frame <= usb->frame_number) {
+				/*
+				 * A periodic pipe that is due but was not
+				 * started - no idle channel, or its split
+				 * window is closed - is only retried from a
+				 * SOF, so do not sleep past it.
+				 */
+				if (ttype == CVMX_USB_TRANSFER_ISOCHRONOUS ||
+				    ttype == CVMX_USB_TRANSFER_INTERRUPT)
+					due_now = true;
+			} else if (pipe->next_tx_frame < min_due) {
 				min_due = pipe->next_tx_frame;
+			}
 		}
 	}
 	if (min_due != ~0ull) {
@@ -1983,7 +1995,7 @@ done:
 		 * a few frames. Stay well below the 16383-frame wrap of
 		 * HFNUM. One (micro)frame is 125us in high-speed mode.
 		 */
-		if (delta <= 4 || delta > 8000)
+		if (due_now || delta <= 4 || delta > 8000)
 			need_sof = 1;
 		else
 			hrtimer_start(&usb->sof_timer,
Signature · 1 line
2.47.0
#1 lore raw

Hi Greg,

A gentle ping on this one. It fixes aebbc7d63407 ("usb: octeon-hcd: sleep on an hrtimer for far-off periodic transfers"), which came in with the usb-7.3-rc6 pull, so 7.3 will ship with the regression unless this is picked up: a periodic pipe that is due but could not be started can wait up to a second for the next SOF.

If it looks fine, could it go to Linus through usb-linus? If you would like anything changed, I will respin.

Thanks,
Orgad

maintainer
#2 lore raw
Quoted 10 lines · Orgad Shaneh

Hi Greg,

A gentle ping on this one. It fixes aebbc7d63407 ("usb: octeon-hcd: sleep on an hrtimer for far-off periodic transfers"), which came in with the usb-7.3-rc6 pull, so 7.3 will ship with the regression unless this is picked up: a periodic pipe that is due but could not be started can wait up to a second for the next SOF.

If it looks fine, could it go to Linus through usb-linus? If you would like anything changed, I will respin.

Sorry, but there is no context here, where is the patch?

And I am way behind in patch review due to travel and conferences, will be catching up "soon".

thanks,

greg k-h