From: Takashi Iwai <tiwai@suse.de>
To: Carl Hetherington <lists@carlh.net>
Cc: alsa-devel@alsa-project.org
Subject: Re: Query about xrun on usb/pcm
Date: Tue, 22 Nov 2022 08:25:29 +0100 [thread overview]
Message-ID: <87y1s3v4ba.wl-tiwai@suse.de> (raw)
In-Reply-To: <b4e71631-4a94-613-27b2-fb595792630@carlh.net>
On Mon, 21 Nov 2022 22:14:39 +0100,
Carl Hetherington wrote:
>
> Hi all,
>
> I wonder if anybody has any clues/suggestions about problem I'm seeing
> with an XMOS-based USB sound card.
>
> As far as I can see, the card has endpoint 0x82 set up for capture data,
> 0x2 for playback data, and 0x82 is also used as the sync endpoint for
> playback. I'm assuming that's a fairly common arrangement?
Yes, that's an oft-seen implicit feedback mode.
You seem hitting a corner case of dealing with that mode...
> I am testing it using simultaneous playback and capture, and simulating
> a high-CPU-load case by sleeping for long enough to cause a lot of
> xruns. After some random time, I see a failure case that I'm struggling
> to explain. It goes like this:
>
> There's an XRUN on the playback PCM, so __snd_pcm_xrun happens, then
> stop_endpoints() happens, and:
> it decides not to stop 0x82 because its running is > 1
> it stops 0x2, so its state goes to EP_STATE_STOPPING
>
> Then the ALSA userspace code calls prepare on the playback PCM to get it
> going again.
>
> This ends up in wait_clear_urbs(), which does nothing with 0x82 as it is
> still running.
So far, so good.
> At this point, the prepare thread is interrupted by an XRUN on
> the capture PCM. With this PCM, there is no sync endpoint, and 0x82 is the data
> endpoint.
> In the xrun handler:
> stop_urbs() sets 0x82 to EP_STATE_STOPPING.
> ... and the xrun handler finishes.
>
> Then we end up back in the prepare for the playback PCM.
> wait_clear_urbs() then sets 0x2 to STOPPED, and the prepare is finished.
>
> Now, snd_usb_endpoint_start() is called on 0x2 and that is fine. Next,
> snd_usb_endpoint_start() is called on 0x82 and that fails because its
> state is still STOPPING.
>
> At this point things seem broken.
>
> Does anyone have a hint about where in this sequence things are going
> wrong, and maybe even why?
The problem is that it's treating XRUNs on the both streams
individually. It's correct to recover only the PCM stream when an
XRUN is reported to the PCM stream. However, for an XRUN on the
capture stream that serves as a sync source, it should stop and
recover not only the capture PCM stream but also the playback stream
as a sync sink as well.
Below is a possible test fix (totally untested!).
This may give XRUNs twice eventually, which is a bit confusing, but it
aligns with the actual hardware behavior, at least.
thanks,
Takashi
-- 8< --
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -403,10 +403,15 @@ static int prepare_inbound_urb(struct snd_usb_endpoint *ep,
static void notify_xrun(struct snd_usb_endpoint *ep)
{
struct snd_usb_substream *data_subs;
+ struct snd_usb_endpoint *ep_sink;
data_subs = READ_ONCE(ep->data_subs);
- if (data_subs && data_subs->pcm_substream)
+ if (data_subs && data_subs->pcm_substream) {
snd_pcm_stop_xrun(data_subs->pcm_substream);
+ ep_sink = READ_ONCE(ep->sync_sink);
+ if (ep_sink)
+ notify_xrun(ep_sink);
+ }
}
static struct snd_usb_packet_info *
next prev parent reply other threads:[~2022-11-22 7:26 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-21 21:14 Query about xrun on usb/pcm Carl Hetherington
2022-11-22 7:25 ` Takashi Iwai [this message]
2022-11-22 11:16 ` Carl Hetherington
2022-11-22 14:19 ` Takashi Iwai
2022-11-22 14:22 ` Takashi Iwai
2022-11-28 22:51 ` Carl Hetherington
2022-11-29 7:45 ` Takashi Iwai
2022-11-30 22:37 ` Carl Hetherington
2022-12-01 7:47 ` Takashi Iwai
2022-12-05 11:59 ` Carl Hetherington
2022-12-05 12:33 ` Takashi Iwai
2022-12-05 18:53 ` Carl Hetherington
2022-12-06 7:51 ` Takashi Iwai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87y1s3v4ba.wl-tiwai@suse.de \
--to=tiwai@suse.de \
--cc=alsa-devel@alsa-project.org \
--cc=lists@carlh.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.