Skip to content

Commit eee5d6f

Browse files
committed
ALSA: usb-audio: Switch back to non-latency mode at a later point
The recent regression report revealed that the judgment of the low-latency playback mode based on the runtime->stop_threshold cannot work reliably at the prepare stage, as sw_params call may happen at any time, and PCM dmix actually sets it up after the prepare call. This ended up with the stall of the stream as PCM ack won't be issued at all. For addressing this, check the free-wheeling mode again at the PCM trigger right before starting the stream again, and allow switching to the non-LL mode at a late stage. Fixes: d5f871f ("ALSA: usb-audio: Improved lowlatency playback support") Reported-and-tested-by: Kirill A. Shutemov <[email protected]> Link: https://lore.kernel.org/r/[email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 76c4718 commit eee5d6f

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

sound/usb/pcm.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,12 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
581581
return 0;
582582
}
583583

584+
/* free-wheeling mode? (e.g. dmix) */
585+
static int in_free_wheeling_mode(struct snd_pcm_runtime *runtime)
586+
{
587+
return runtime->stop_threshold > runtime->buffer_size;
588+
}
589+
584590
/* check whether early start is needed for playback stream */
585591
static int lowlatency_playback_available(struct snd_pcm_runtime *runtime,
586592
struct snd_usb_substream *subs)
@@ -592,8 +598,7 @@ static int lowlatency_playback_available(struct snd_pcm_runtime *runtime,
592598
/* disabled via module option? */
593599
if (!chip->lowlatency)
594600
return false;
595-
/* free-wheeling mode? (e.g. dmix) */
596-
if (runtime->stop_threshold > runtime->buffer_size)
601+
if (in_free_wheeling_mode(runtime))
597602
return false;
598603
/* implicit feedback mode has own operation mode */
599604
if (snd_usb_endpoint_implicit_feedback_sink(subs->data_endpoint))
@@ -1552,6 +1557,8 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea
15521557
subs);
15531558
if (subs->lowlatency_playback &&
15541559
cmd == SNDRV_PCM_TRIGGER_START) {
1560+
if (in_free_wheeling_mode(substream->runtime))
1561+
subs->lowlatency_playback = false;
15551562
err = start_endpoints(subs);
15561563
if (err < 0) {
15571564
snd_usb_endpoint_set_callback(subs->data_endpoint,

0 commit comments

Comments
 (0)