Re: [PATCH] ALSA: usb-audio: add IFB_SILENCE_ON_EMPTY quirk for Behringer Flow 8
Mark Shi <[email protected]> Thu, 30 Jul 2026 23:40:11 +0800
| Newsgroups | org.kernel.vger.linux-sound,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <OS3PR01MB8827209050FF390ABE33A4E2DEC92@OS3PR01MB8827.jpnprd01.prod.outlook.com> |
Hi Takashi, 在 2026/7/30 21:13, Takashi Iwai 写道: > On Thu, 30 Jul 2026 14:33:44 +0200, > Mark Shi wrote: >> Hi Takashi, >> >>> On Wed, 29 Jul 2026 16:28:23 +0200, >>> Mark Shi wrote: >>>> Hi Takashi, >>>> >>>> On Tue, 28 Jul 2026 17:46:05 +0200, >>>> Mark Shi wrote: >>>> Hi Takashi, >>>> 在 2026/7/28 23:02, Takashi Iwai 写道: >>>> On Tue, 28 Jul 2026 16:27:35 +0200, >>>> Mark Shi wrote: >>>> Hi Gordon, >>>> 在 2026/5/26 15:29, Gordon Chen >>>> 写道: >>>> The Behringer Flow 8 >>>> (1397:050c) is an 8-channel USB mixer that >>>> declares OUT EP 0x01 with implicit feedback from capture EP 0x81 via >>>> its UAC2 endpoint companion descriptor. After 5-35 minutes of >>>> continuous playback, the device occasionally returns a capture URB in >>>> which every iso_frame_desc has a non-zero status (-EXDEV bursts, >>>> visible as rate-limited "frame N active: -18" lines in dmesg from >>>> pcm.c). >>>> In that case >>>> snd_usb_handle_sync_urb() at endpoint.c counts bytes==0 >>>> and falls into the early "skip empty packets" return originally added >>>> for M-Audio Fast Track Ultra. As a result the playback EP loses its >>>> sole IFB-driven feeder and the OUT ring starves permanently: hw_ptr >>>> stops advancing while substream state remains RUNNING. Only USB >>>> re-enumeration recovers. >>>> Three independent ftrace >>>> captures (taken at the moment of stall via a >>>> userspace watchdog) consistently show: >>>> - 60-70 capture URB >>>> completions in the 70ms window before the marker >>>> - 0 retire_playback_urb / queue_pending_output_urbs / >>>> snd_usb_endpoint_implicit_feedback_sink calls >>>> - every usb_submit_urb in the window comes from >>>> snd_complete_urb+0x64e (capture self-resubmit), none from the >>>> queue_pending_output_urbs path >>>> Add a new opt-in quirk >>>> QUIRK_FLAG_IFB_SILENCE_ON_EMPTY: when set, the >>>> early return is skipped and we fall through to enqueue a packet_info >>>> whose packet_size[i] are all 0 (the existing loop already maps >>>> status!=0 packets to size 0). prepare_outbound_urb then emits a >>>> silence packet, the OUT ring keeps moving, and the device rides >>>> through the glitch. >>>> The default behaviour >>>> (early return) is preserved for all existing >>>> devices including M-Audio Fast Track Ultra. Only Flow 8 opts in here. >>>> Cc: >>>> [email protected] >>>> Signed-off-by: Gordon Chen <[email protected]> >>>> >>>> Device: Mechrevo WUJIE14Pro A-7BC4U >>>> CPU: AMD Ryzen 7 7840HS (Codename "Phoenix") >>>> Firmware Version: T140_PHX_V20 >>>> Firmware Release Date: 2024.1.8 >>>> Kernel version: 7.1.4 >>>> In Linux kernel 7.1.4, I found >>>> that my laptop couldn't wake up from S3 >>>> suspend; I had to hold down the power button to force a shutdown and >>>> then restart it. >>>> Using `git bisect`, I discovered >>>> that if I revert this patch, the >>>> laptop resumes from S3 normally. >>>> Do you have this USB-audio device >>>> (Behringer Flow 8 with USB ID >>>> 1397:050c)? The commit must be harmless unless you have this device. >>>> That is, if you don't have this device, it's likely a false-positive >>>> bisection result. >>>> >>>> thanks, >>>> Takashi >>>> I don't have that device, but I partially >>>> reverted the code in that >>>> section, and it went back to normal. >>>> Hmm, that's odd. >>>> Could you put a debug print what value does >>>> ep->chip->quirk_flags >>>> have on your device? >>>> >>>> thanks, >>>> Takashi >>>> I added `usb_audio_info`, compiled and booted, but `dmesg | >>>> grep "quirk_flags" >>>> ` returned no output. >>> Then something wrong in your test :) >>> >>> Put another debug print at another place like the probe function, in >>> order to verify whether the patched driver is really loaded, too. >>> And, make sure that you're running the exactly patched kernel. >>> >>> >>> Takashi >> >> I used the `printk` function to retrieve the `quirk_flags` for the >> current function. Here is the output: >> >> ``` >> >> [ 23.225719] snd-usb-audio: quirk_flags = 0x100800 >> > And what about ep->chip->quirk_flags at the place in question? Does > it show the very same value? > > The value 0x100800 means that your device has the quirk bit 11 > (QUIRK_TYPE_IFACE_DELAY) and bit 20 (QUIRK_TYPE_FORCE_IFACE_RESET), > and they have nothing to do with the commit you're testing. > > > thanks, > Takashi I modified the output and added two log points for this purpose, and output: ``` [ 23.355939] snd-usb-audio:snd_usb_endpoint_start() quirk_flags = 0x100800 [ 23.437401] snd-usb-audio:snd_usb_endpoint_start() quirk_flags = 0x100800 [ 67.813139] snd-usb-audio:snd_usb_endpoint_start() quirk_flags = 0x100800 ``` Regardless of whether I added a log point, `snd_usb_endpoint_implicit_feedback_sink()` did not produce any output. However, without the partial code rollback, during the 7.1.3–7.1.4 period, I could only restore normal operation by disabling PCIe power management using the "pcie_port_pm=off" kernel parameter (from "amd_s2idle.py" script's report). Unfortunately for me, the platform returned to normal in version 7.1.5 (even though I hadn't applied any patches) (T_T). This makes it impossible for me to determine which side is at fault. --- sound/usb/endpoint.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 24cd7692bd01..cc79f4e9cf10 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -1559,6 +1559,8 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep) int err; unsigned int i; + printk(KERN_EMERG "snd-usb-audio:snd_usb_endpoint_start() quirk_flags = 0x%x\n", ep->chip->quirk_flags); + if (atomic_read(&ep->chip->shutdown)) return -EBADFD; @@ -1789,7 +1791,9 @@ static void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, * packet_info with size 0 packets, so playback emits silence * and the OUT ring keeps moving. */ + printk(KERN_EMERG "snd-usb-audio:snd_usb_endpoint_implicit_feedback_sink() quirk_flags = 0x%x\n", ep->chip->quirk_flags); if (bytes == 0 && !(ep->chip->quirk_flags & QUIRK_FLAG_IFB_SILENCE_ON_EMPTY)) + // if (bytes == 0) return; spin_lock_irqsave(&ep->lock, flags); -- 2.55.0 -- Best Regards, Mark Shi