Re: [PATCH v3] ALSA: usb-audio: Fix boot-time audio stuttering for USB Audio device
Zhang Heng <[email protected]>
| Newsgroups | gmane.linux.sound,gmane.linux.kernel,gmane.linux.usb.general |
|---|---|
| Message-ID | <[email protected]> |
> 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. > I tested this on the original version without this change, and the performance was quite poor. However, I am not familiar with this area, so I cannot provide a professional explanation. In fact, I originally debugged this issue on the 5.4 stable branch, and it worked basically fine even without this change. The most important part is the fix below. > 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