[alsa-devel] 2.6.30: xruns caused by "ALSA: pcm - Safer boundary checks"
Takashi Iwai
tiwai at suse.de
Wed May 27 12:41:34 CEST 2009
At Wed, 27 May 2009 09:25:57 +0200 (CEST),
Jaroslav Kysela wrote:
>
> On Wed, 27 May 2009, Takashi Iwai wrote:
>
> > Thanks for testing!
> >
> > I have an impression that the jiffies check can behave pretty buggy in
> > cases the hardware doesn't give a smooth pointer update. It's
> > supposed to filter out spontaneous invalid pointer values. That'll
> > work indeed (although I don't think the check in
> > snd_pcm_period_elapsed() is worth). But what if a hardware returns
> > the pointer value that is not always updated smoothly?
> >
> > Assume a hardware returning only spontaneously updated values, 0 at
> > t=0, 1000 at t=100, 2000 at t=200, and so on. If
> > snd_pcm_update_hw_ptr() is called at t=99, it gets still position 0.
> > Then when it's called at t=100, it suddenly increases to position 1000
> > while jiffies delta is only 1. The current code would filter out this
> > update because it appears as if too much.
>
> That's good point. The hw_ptr_jiffies should be updated only when position
> in the ring buffer moves:
>
> if (runtime->status->hw_ptr != new_hw_ptr)
> runtime->hw_ptr_jiffies = jiffies;
>
> Similar condition might be also used for runtime->status->tstamp variable.
Yep, that'll be needed.
> > The problem continues, if snd_pcm_update_hw_ptr() is constantly called
> > at each t=100, 101, ... At each call, jiffies delta is 1, but the
> > position delta is still 1000 because it wasn't updated. That is, as
> > long as the app keeps calling snd_pcm_update_hw_ptr(), the position
> > won't be updated. This is pretty possible especially with an app like
> > pulseaudio.
> >
> >
> > I have a feeling that we should disable the jiffies check in that
> > part, at least for 2.6.30, until a better solution is found. The
> > jiffies check is already done and works pretty well in the driver
> > side (hda-intel and intel8x0). But this check in the PCM core can be
> > (not always, though) buggy, and actually gives problems sometimes.
>
> As I already wrote, I have nothing against to make jiffies check
> conditional on xrun_debug() for 2.6.30 for debugging purposes, but I'd
> like to leave this code enabled in our development trees. It reveals some
> buggy drivers which should be checked (a new one is Vortex - au88x0).
OK, I created a patch below and will included in the next pull
request today or tomorrow.
thanks,
Takashi
===
From c87d9732004b3f8fd82d729f12ccfb96c0df279e Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai at suse.de>
Date: Wed, 27 May 2009 10:53:33 +0200
Subject: [PATCH] ALSA: Enable PCM hw_ptr_jiffies check only in xrun_debug mode
The PCM hw_ptr jiffies check results sometimes in problems when a
hardware doesn't give smooth hw_ptr updates. So far, au88x0 and some
other drivers appear not working due to this strict check.
However, this check is a nice debug tool, and the capability should be
still kept.
Hence, we disable this check now as default unless the user enables it
by setting the xrun_debug mode to the specific stream via a proc file.
Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
Documentation/sound/alsa/Procfile.txt | 5 +++++
sound/core/pcm_lib.c | 9 ++++++++-
2 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/Documentation/sound/alsa/Procfile.txt b/Documentation/sound/alsa/Procfile.txt
index bba2dbb..cfac20c 100644
--- a/Documentation/sound/alsa/Procfile.txt
+++ b/Documentation/sound/alsa/Procfile.txt
@@ -104,6 +104,11 @@ card*/pcm*/xrun_debug
When this value is greater than 1, the driver will show the
stack trace additionally. This may help the debugging.
+ Since 2.6.30, this option also enables the hwptr check using
+ jiffies. This detects spontaneous invalid pointer callback
+ values, but can be lead to too much corrections for a (mostly
+ buggy) hardware that doesn't give smooth pointer updates.
+
card*/pcm*/sub*/info
The general information of this PCM sub-stream.
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 3eea98a..d659995 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -249,6 +249,11 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
new_hw_ptr = hw_base + pos;
}
}
+
+ /* Do jiffies check only in xrun_debug mode */
+ if (!xrun_debug(substream))
+ goto no_jiffies_check;
+
/* Skip the jiffies check for hardwares with BATCH flag.
* Such hardware usually just increases the position at each IRQ,
* thus it can't give any strange position.
@@ -336,7 +341,9 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
hw_base = 0;
new_hw_ptr = hw_base + pos;
}
- if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
+ /* Do jiffies check only in xrun_debug mode */
+ if (xrun_debug(substream) &&
+ ((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
hw_ptr_error(substream,
"hw_ptr skipping! "
"(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n",
--
1.6.3
More information about the Alsa-devel
mailing list