From: Takashi Iwai <tiwai@suse.de>
To: Leonard Crestez <cdleonard@gmail.com>
Cc: Takashi Iwai <tiwai@suse.com>,
linux-sound@vger.kernel.org, Jaroslav Kysela <perex@perex.cz>,
linux-kernel@vger.kernel.org
Subject: Re: [RFC] ALSA: usb-audio: Fix missing xrun report in lowlatency mode
Date: Wed, 20 Nov 2024 09:33:36 +0100 [thread overview]
Message-ID: <87v7wi484f.wl-tiwai@suse.de> (raw)
In-Reply-To: <874j425pjz.wl-tiwai@suse.de>
On Wed, 20 Nov 2024 08:31:44 +0100,
Takashi Iwai wrote:
>
> On Tue, 19 Nov 2024 22:54:19 +0100,
> Leonard Crestez wrote:
> >
> > Hello,
> >
> > I’m investigating an issue where USB Audio does not properly send
> > XRUN notifications.
> >
> > The issue can be reproduced with aplay: enable xrun_debug, aplay -D
> > plughw:0 and CTRL-Z - no XRUN message is seen
> >
> > Disabling lowlatency_playback via modprobe parameter does make this
> > issue go away - XRUNs are reported correctly without any changes.
> >
> >
> > After a lot of tracing the following seems to be happening:
> >
> > - prepare_playback_urb find avail=48, meaning 48 bytes still to-be-played
> > - snd_usb_endpoint_next_packet_size decides that 48 is too little and
> > returns -EAGAIN. Specifically -EAGAIN is returned from
> > next_packet_size
> > - The return value of prepare_playback_urb is propagated through
> > prepare_outbound_urb back to snd_usb_queue_pending_output_urbs
> > - snd_usb_queue_pending_output_urbs receives -EAGAIN from
> > prepare_outbound_urb
> > - since err is -EAGAIN the ctx is pushed back to the ready list and
> > transmission is aborted but notify_xrun is skipped
> > - no more playback?
> >
> > It is possible to make XRUNs happen by caling notify_xrun even on
> > -EAGAIN, diff looks like this:
> >
> > diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
> > index 568099467dbb..da64ee0cf60a 100644
> > --- a/sound/usb/endpoint.c
> > +++ b/sound/usb/endpoint.c
> > @@ -495,10 +495,11 @@ int snd_usb_queue_pending_output_urbs(struct
> > snd_usb_endpoint *ep,
> > break;
> > if (err < 0) {
> > /* push back to ready list again for -EAGAIN */
> > if (err == -EAGAIN) {
> > push_back_to_ready_list(ep, ctx);
> > + notify_xrun(ep);
> > break;
> > }
> >
> > if (!in_stream_lock)
> > notify_xrun(ep);
> >
> >
> > This mail was not formatted as proper patch because this seems very
> > likely incorrect, it undoes an explicit check. What would a correct
> > solution look like?
>
> The -EAGAIN there itself doesn't mean the crucial xrun yet. There may
> be still pending URBS to be processed. The real XRUN happens only
> when there is no URBs pending, hence nothing will be taken further --
> at least for low-latency operation. (In the case of implicit feedback
> mode, it can be driven by the feedback from the capture stream, and
> the empty URB check might be wrong.)
>
> Could you check the change below? (totally untested)
A bit more change would be needed because it can lead to a false xrun
at draining. At stopping, it shouldn't reach to that code path.
The revised patch is below.
Takashi
--- 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_pcm_substream *psubs;
data_subs = READ_ONCE(ep->data_subs);
- if (data_subs && data_subs->pcm_substream)
- snd_pcm_stop_xrun(data_subs->pcm_substream);
+ if (!data_subs)
+ return;
+ psubs = data_subs->pcm_substream;
+ if (psubs && psubs->runtime &&
+ psubs->runtime->state == SNDRV_PCM_STATE_RUNNING)
+ snd_pcm_stop_xrun(psubs);
}
static struct snd_usb_packet_info *
@@ -562,7 +567,10 @@ static void snd_complete_urb(struct urb *urb)
push_back_to_ready_list(ep, ctx);
clear_bit(ctx->index, &ep->active_mask);
snd_usb_queue_pending_output_urbs(ep, false);
- atomic_dec(&ep->submitted_urbs); /* decrement at last */
+ /* decrement at last, and check xrun */
+ if (atomic_dec_and_test(&ep->submitted_urbs) &&
+ !snd_usb_endpoint_implicit_feedback_sink(ep))
+ notify_xrun(ep);
return;
}
next prev parent reply other threads:[~2024-11-20 8:33 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-19 21:54 [RFC] ALSA: usb-audio: Fix missing xrun report in lowlatency mode Leonard Crestez
2024-11-20 7:31 ` Takashi Iwai
2024-11-20 8:33 ` Takashi Iwai [this message]
2024-11-20 21:02 ` Leonard Crestez
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=87v7wi484f.wl-tiwai@suse.de \
--to=tiwai@suse.de \
--cc=cdleonard@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=perex@perex.cz \
--cc=tiwai@suse.com \
/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.