Linux USB
 help / color / mirror / Atom feed
* Re: [PATCH v3] ALSA: usb-audio: Fix boot-time audio stuttering for USB Audio device
       [not found] <20260728111309.1271834-1-zhangheng@kylinos.cn>
@ 2026-08-16 16:01 ` Michal Pecio
  0 siblings, 0 replies; only message in thread
From: Michal Pecio @ 2026-08-16 16:01 UTC (permalink / raw)
  To: Zhang Heng
  Cc: perex, tiwai, kees, chengordon326, jussi, hulianqin, i, g,
	cryolitia, pav, linux-sound, linux-kernel, linux-usb

Hi,

Adding linux-usb.

On Tue, 28 Jul 2026 19:13:09 +0800, Zhang Heng wrote:
> This USB Audio device (0x1e0b:0xd01e) exhibits audio stuttering
> during boot when playing audio. Once the system is fully booted,
> playback is normal.

Weird, your thread runs horribly slowly (preempted by something despite
spin_lock_irqsave held by xhci-hcd?) during those URB submissions. It's
first time I actually see this warning:

[    9.654586] xhci_hcd 0000:03:00.3: Frame ID 644 (reg 5154, index 13) beyond range (645, 1539)
[    9.654589] xhci_hcd 0000:03:00.3: Ignore frame ID field, use SIA bit instead
[    9.655053] xhci_hcd 0000:03:00.3: Frame ID 644 (reg 5158, index 14) beyond range (645, 1539)
[    9.655055] xhci_hcd 0000:03:00.3: Ignore frame ID field, use SIA bit instead

If packet 14 was scheduled for frame 644, packet 0 must have been
frame 643 i.e. uframe 5144 (should be frame aligned). So packet 14 was
uframe 5158 - it was only being written to HW while it was already
due for execution, some 2ms after usb_submit_urb() began. ???

URB execution won't even start until all packets are written - we do
take care to queue URBs atomically. Initial part of this URB (before
the warnings) will complete with -EXDEV status due to blatant isoc
scheduling threshold violation, but the rest (with SIA bits) will be
delayed by HW and completed normally after submission finishes.

The same may happen to the next URB if the condition which caused this
persists, and moreover, the next URB may be scheduled with a gap after
the previous one.

IDK how snd-usb-audio would react to such a mess. It is believed, at
least by the USB subsystem, that drivers expect contiguously submitted
URBs to execute in contiguous service intervals, without gaps.

FYI, a lot of this xhci-hcd logic is considered broken and goes out
the window in v7.3. I'm curious if you could test how things work on
usb-next without (and maybe also with) your workaround code.

https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git/log/?h=usb-next

This removes the automatic conversion to SIA/ASAP and insertion of gaps
between URBs, so that the initial URB will likely wholly complete with
-EXDEV and the next one will be scheduled immediately after it.

Again, what snd-usb-audio will think about it IDK, but usb-next mostly
works for me in my test (one remaining exception I'm trying to fix).

> The device reports its isochronous endpoints with the Asynchronous
> sync type (bmAttributes = 0x03), which causes the driver to
> calculate nurbs = min(max_urbs, ...) = 3, providing only ~16ms
> of buffering. During boot, the higher system scheduling jitter
> (e.g., from init scripts, device enumeration, and driver probing)
> can exceed this buffer depth, causing audible stuttering.

Not sure what causes it, xhci-hcd holds a spin_lock_irqsave() during
the whole submission, so I think it shouldn't get preempted.

> This patch adds a device-specific quirk (QUIRK_FLAG_PLAYBACK_URB_FIXUP)
> that applies two changes for this device:
> 1. Forces nurbs to MAX_URBS (12), providing sufficient buffering

I actually wonder why snd-usb-audio seems to allocate only one URB per
period and then submit URBs shorter than a period. Doesn't this mean
that all URBs may be busy without covering the whole playback buffer,
and then newly written samples have nowhere to go until one completes?

This seems to increase risk of URB queue underrun, though TBH I tried
increasing 'nurbs' and I haven't seen much practical difference running
with very low latency like 2x250us or 2x500us.

Note: on USB 3.1 and newer such settings may only work on usb-next.

> 2. Sets URB_ISO_ASAP flag for more consistent xHCI scheduling

URB_ISO_ASAP or xHCI SIA do the opposite of consistency - they cause
execution to be delayed until the URB is written to the HW and the HW
reaches it.

Non-ASAP submissions are scheduled contiguously and possibly complete
with -EXDEV if submitted too late. Only after the last completion of
the last remaining URB returns, will the next URB be scheduled
separately and discontiguously, to execute in some (near) future.
Again, this is documented usb_submit_urb() rule and it's believed that
drivers expect it. It's how OHCI/UHCI/EHCI drivers work.

Using ASAP is a known workaround for the old xhci-hcd bugs, similar
patches have been sent to linux-usb, that's why it's being fixed. But
IDK if usb-next will solve your bizarre edge case out of the box.

Regards,
Michal

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-08-16 15:59 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20260728111309.1271834-1-zhangheng@kylinos.cn>
2026-08-16 16:01 ` [PATCH v3] ALSA: usb-audio: Fix boot-time audio stuttering for USB Audio device Michal Pecio

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox