linux/sound/usb
Takashi Iwai d5f871f89e ALSA: usb-audio: Improved lowlatency playback support
This is another attempt to improve further the handling of playback
stream in the low latency mode.  The latest workaround in commit
4267c5a8f3 ("ALSA: usb-audio: Work around for XRUN with low latency
playback") revealed that submitting URBs forcibly in advance may
trigger XRUN easily.  In the classical mode, this problem was avoided
by practically delaying the submission of the actual data with the
pre-submissions of silent data before triggering the stream start.
But that is exactly what we want to avoid.

Now, in this patch, instead of the previous workaround, we take a
similar approach as used in the implicit feedback mode.  The URBs are
queued at the PCM trigger start like before, but we check whether the
buffer has been already filled enough before each submission, and
stop queuing if the data overcomes the threshold.  The remaining URBs
are kept in the ready list, and they will be retrieved in the URB
complete callback of other (already queued) URBs.  In the complete
callback, we try to fill the data and submit as much as possible
again.  When there is no more available in-flight URBs that may handle
the pending data, we'll check in PCM ack callback and submit and
process URBs there in addition.  In this way, the amount of in-flight
URBs may vary dynamically and flexibly depending on the available data
without hitting XRUN.

The following things are changed to achieve the behavior above:

* The endpoint prepare callback is changed to return an error code;
  when there is no enough data available, it may return -EAGAIN.
  Currently only prepare_playback_urb() returns the error.

  The evaluation of the available data is a bit messy here; we can't
  check with snd_pcm_avail() at the point of prepare callback (as
  runtime->status->hwptr hasn't been updated yet), hence we manually
  estimate the appl_ptr and compare with the internal hwptr_done to
  calculate the available frames.

* snd_usb_endpoint_start() doesn't submit full URBs if the prepare
  callback returns -EAGAIN, and puts the remaining URBs to the ready
  list for the later submission.

* snd_complete_urb() treats the URBs in the low-latency mode similarly
  like the implicit feedback mode, and submissions are done in
  (now exported) snd_usb_queue_pending_output_urbs().

* snd_usb_queue_pending_output_urbs() again checks the error value
  from the prepare callback.  If it's -EAGAIN for the normal stream
  (i.e. not implicit feedback mode), we push it back to the ready list
  again.

* PCM ack callback is introduced for the playback stream, and it calls
  snd_usb_queue_pending_output_urbs() if there is no in-flight URB
  while the stream is running.  This corresponds to the case where the
  system needs the appl_ptr update for re-submitting a new URB.

* snd_usb_queue_pending_output_urbs() and the prepare EP callback
  receive in_stream_lock argument, which is a bool flag indicating the
  call path from PCM ack.  It's needed for avoiding the deadlock of
  snd_pcm_period_elapsed() calls.

* Set the new SNDRV_PCM_INFO_EXPLICIT_SYNC flag when the new
  low-latency mode is deployed.  This assures catching each applptr
  update even in the mmap mode.

Fixes: 4267c5a8f3 ("ALSA: usb-audio: Work around for XRUN with low latency playback")
Link: https://lore.kernel.org/r/20210929080844.11583-9-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-09-30 13:55:24 +02:00
..
6fire module: remove never implemented MODULE_SUPPORTED_DEVICE 2021-03-17 13:16:18 -07:00
bcd2000 ALSA: Convert strlcpy to strscpy when return value is unused 2021-01-08 09:30:05 +01:00
caiaq module: remove never implemented MODULE_SUPPORTED_DEVICE 2021-03-17 13:16:18 -07:00
hiface module: remove never implemented MODULE_SUPPORTED_DEVICE 2021-03-17 13:16:18 -07:00
line6 ALSA: line6: Fix racy initialization of LINE6 MIDI 2021-05-19 16:25:57 +02:00
misc module: remove never implemented MODULE_SUPPORTED_DEVICE 2021-03-17 13:16:18 -07:00
usx2y ALSA: usx2y: Prefer struct_size over open coded arithmetic 2021-09-21 18:38:11 +02:00
card.c ALSA: usb-audio: Unify mixer resume and reset_resume procedure 2021-09-13 15:00:31 +02:00
card.h ALSA: usb-audio: Improved lowlatency playback support 2021-09-30 13:55:24 +02:00
clock.c ALSA: usb-audio: fix comment reference in __uac_clock_find_source 2021-09-28 10:17:08 +02:00
clock.h ALSA: usb-audio: Constify audioformat pointer references 2020-11-23 15:15:36 +01:00
endpoint.c ALSA: usb-audio: Improved lowlatency playback support 2021-09-30 13:55:24 +02:00
endpoint.h ALSA: usb-audio: Improved lowlatency playback support 2021-09-30 13:55:24 +02:00
format.c ALSA: usb-audio: Move rate validation quirk into quirk_flags 2021-08-02 09:06:03 +02:00
format.h ALSA: usb: initial USB Audio Device Class 3.0 support 2018-03-21 11:46:33 +01:00
helper.c ALSA: usb-audio: Add snd_usb_get_host_interface() helper 2020-11-23 15:13:47 +01:00
helper.h ALSA: usb-audio: Add snd_usb_get_host_interface() helper 2020-11-23 15:13:47 +01:00
implicit.c ALSA: usb-audio: Move playback_first flag into quirk_flags 2021-08-02 09:05:58 +02:00
implicit.h ALSA: usb-audio: Factor out the implicit feedback quirk code 2020-11-23 15:17:00 +01:00
Kconfig sound: Fix Kconfig indentation 2019-10-07 03:53:03 +02:00
Makefile ALSA: usb-audio: Factor out the implicit feedback quirk code 2020-11-23 15:17:00 +01:00
media.c ALSA: usb-audio: fix spelling mistakes 2021-07-05 19:33:54 +02:00
media.h media: sound/usb: Use Media Controller API to share media resources 2019-04-22 11:21:06 -04:00
midi.c ALSA: usb-audio: Fix potential out-of-bounce access in MIDI EP parser 2021-05-11 11:10:37 +02:00
midi.h ALSA: usb-audio: generate midi streaming substream names from jack names 2021-03-01 09:21:54 +01:00
mixer_maps.c ALSA: usb-audio: Move ignore_ctl_error check into quirk_flags 2021-08-02 09:06:05 +02:00
mixer_quirks.c ALSA: usb-audio: Unify mixer resume and reset_resume procedure 2021-09-13 15:00:31 +02:00
mixer_quirks.h ALSA: usb-audio: Initialize Dell Dock playback volumes 2018-05-02 16:02:32 +02:00
mixer_s1810c.c ALSA: usb-audio: fix spelling mistakes 2021-07-05 19:33:54 +02:00
mixer_s1810c.h ALSA: usb-audio: Add support for Presonus Studio 1810c 2020-02-15 09:46:16 +01:00
mixer_scarlett_gen2.c ALSA: scarlett2: Fix line out/speaker switching notifications 2021-07-24 10:05:30 +02:00
mixer_scarlett_gen2.h ALSA: usb-audio: scarlett2: Improve driver startup messages 2021-05-21 16:22:52 +02:00
mixer_scarlett.c ALSA: usb-audio: fix spelling mistakes 2021-07-05 19:33:54 +02:00
mixer_scarlett.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
mixer_us16x08.c ALSA: Convert strlcpy to strscpy when return value is unused 2021-01-08 09:30:05 +01:00
mixer_us16x08.h ALSA: usb: Constify snd_kcontrol_new items 2020-01-03 09:24:34 +01:00
mixer.c ALSA: usb-audio: Unify mixer resume and reset_resume procedure 2021-09-13 15:00:31 +02:00
mixer.h ALSA: usb-audio: Unify mixer resume and reset_resume procedure 2021-09-13 15:00:31 +02:00
pcm.c ALSA: usb-audio: Improved lowlatency playback support 2021-09-30 13:55:24 +02:00
pcm.h ALSA: usb-audio: Make snd_usb_pcm_delay() static 2021-06-02 09:01:17 +02:00
power.c ALSA: usb-audio: More validations of descriptor units 2019-08-22 10:35:59 +02:00
power.h ALSA: usb-audio: Initial Power Domain support 2018-07-31 15:01:22 +02:00
proc.c ALSA: usb-audio: Show sync endpoint information in proc outputs 2020-11-23 15:16:45 +01:00
proc.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
quirks-table.h ALSA: usb-audio: Move autosuspend quirk into quirk_flags 2021-08-02 09:06:04 +02:00
quirks.c ALSA: usb-audio: Add registration quirk for JBL Quantum 800 2021-09-01 22:42:28 +02:00
quirks.h ALSA: usb-audio: Move interface setup delay into quirk_flags 2021-08-02 09:06:02 +02:00
stream.c ALSA: usb-audio: Move tx_length quirk handling to quirk_flags 2021-08-02 09:05:57 +02:00
stream.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
usbaudio.h Merge branch 'for-linus' into for-next 2021-08-30 08:04:04 +02:00
validate.c ALSA: usb-audio: Fix endianess in descriptor validation 2020-02-01 09:06:11 +01:00