Query about xrun on usb/pcm

Carl Hetherington lists at carlh.net
Wed Nov 30 23:37:39 CET 2022


Hi Takashi,

> > Thanks for the suggestion.  I experimented a little with this, but I
> > think the problem I'm seeing is that (even if the application knows it
> > should retry the snd_pcm_prepare() step) we still end up with an endpoint
> > in EP_STATE_STOPPING while the corresponding stop_operating flag is 0.
>
> Ah, I guess that's a fallout in the logic.  When XRUN happens at start
> -- receiving an -EPIPE error at snd_pcm_do_start() -- then the patch
> sets the XRUN state.  This assumed that the stream gets stopped the
> following snd_pcm_undo_start() call.  Indeed it does stop but there we
> forgot setting stop_operating flag unlike what snd_pcm_stop() does.

Thanks for the hint.  I checked it out again, and in fact I'm seeing the
-EPIPE come back from snd_pcm_do_prepare().  It starts its sync-stop,
another xrun comes in (as we talked about before), it tries to
start_endpoints() and that fails.

A fairly similar thing to what you suggested seems to work for me:

diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index f38c2e5e9a29..0b61943cca98 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1948,9 +1948,17 @@ static void snd_pcm_post_prepare(struct snd_pcm_substream *substream,
 	snd_pcm_set_state(substream, SNDRV_PCM_STATE_PREPARED);
 }

+
+static void snd_pcm_undo_prepare(struct snd_pcm_substream *substream,
+				 snd_pcm_state_t state)
+{
+	substream->runtime->stop_operating = true;
+}
+
 static const struct action_ops snd_pcm_action_prepare = {
 	.pre_action = snd_pcm_pre_prepare,
 	.do_action = snd_pcm_do_prepare,
+	.undo_action = snd_pcm_undo_prepare,
 	.post_action = snd_pcm_post_prepare
 };


Can you see any problems with that?  In the application code I do need
to re-try the snd_pcm_prepare() if one fails with -EPIPE, but with this
undo step the second snd_pcm_prepare() is able to recover the endpoint
states, instead of hitting this problem where it tries to start things
that are STOPPING, but also won't set things to STOPPED because
stop_operating is false.

Thanks and best regards,
Carl




More information about the Alsa-devel mailing list