Commit ec08b144 authored by Ben Gardiner's avatar Ben Gardiner Committed by Takashi Iwai

ALSA: sound, core, pcm_lib: xrun_log: log also in_interrupt

When debugging pcm drivers I found the "period" or "hw" prefix printed
by either XRUN_DEBUG_PERIODUPDATE or XRUN_DEBUG_PERIODUPDATE events,
respectively to be very useful is observing the interplay between
interrupt-context updates and syscall-context updates.

Similarly, when debugging overruns with XRUN_DEBUG_LOG it is useful to
see the context of the last 10 positions.

Add an in_interrupt member to hwptr_log_entry which stores the value of
the in_interrupt parameter of snd_pcm_update_hw_ptr0 when the log entry
is created. Print a "[Q]" prefix when dumping the log entries if
in_interrupt was true.
Signed-off-by: default avatarBen Gardiner <bengardiner@nanometrics.ca>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 7cdd8d73
...@@ -189,6 +189,7 @@ static void xrun(struct snd_pcm_substream *substream) ...@@ -189,6 +189,7 @@ static void xrun(struct snd_pcm_substream *substream)
#define XRUN_LOG_CNT 10 #define XRUN_LOG_CNT 10
struct hwptr_log_entry { struct hwptr_log_entry {
unsigned int in_interrupt;
unsigned long jiffies; unsigned long jiffies;
snd_pcm_uframes_t pos; snd_pcm_uframes_t pos;
snd_pcm_uframes_t period_size; snd_pcm_uframes_t period_size;
...@@ -204,7 +205,7 @@ struct snd_pcm_hwptr_log { ...@@ -204,7 +205,7 @@ struct snd_pcm_hwptr_log {
}; };
static void xrun_log(struct snd_pcm_substream *substream, static void xrun_log(struct snd_pcm_substream *substream,
snd_pcm_uframes_t pos) snd_pcm_uframes_t pos, int in_interrupt)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_pcm_hwptr_log *log = runtime->hwptr_log; struct snd_pcm_hwptr_log *log = runtime->hwptr_log;
...@@ -220,6 +221,7 @@ static void xrun_log(struct snd_pcm_substream *substream, ...@@ -220,6 +221,7 @@ static void xrun_log(struct snd_pcm_substream *substream,
return; return;
} }
entry = &log->entries[log->idx]; entry = &log->entries[log->idx];
entry->in_interrupt = in_interrupt;
entry->jiffies = jiffies; entry->jiffies = jiffies;
entry->pos = pos; entry->pos = pos;
entry->period_size = runtime->period_size; entry->period_size = runtime->period_size;
...@@ -246,9 +248,11 @@ static void xrun_log_show(struct snd_pcm_substream *substream) ...@@ -246,9 +248,11 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
entry = &log->entries[idx]; entry = &log->entries[idx];
if (entry->period_size == 0) if (entry->period_size == 0)
break; break;
snd_printd("hwptr log: %s: j=%lu, pos=%ld/%ld/%ld, " snd_printd("hwptr log: %s: %sj=%lu, pos=%ld/%ld/%ld, "
"hwptr=%ld/%ld\n", "hwptr=%ld/%ld\n",
name, entry->jiffies, (unsigned long)entry->pos, name, entry->in_interrupt ? "[Q] " : "",
entry->jiffies,
(unsigned long)entry->pos,
(unsigned long)entry->period_size, (unsigned long)entry->period_size,
(unsigned long)entry->buffer_size, (unsigned long)entry->buffer_size,
(unsigned long)entry->old_hw_ptr, (unsigned long)entry->old_hw_ptr,
...@@ -326,7 +330,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, ...@@ -326,7 +330,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
} }
pos -= pos % runtime->min_align; pos -= pos % runtime->min_align;
if (xrun_debug(substream, XRUN_DEBUG_LOG)) if (xrun_debug(substream, XRUN_DEBUG_LOG))
xrun_log(substream, pos); xrun_log(substream, pos, in_interrupt);
hw_base = runtime->hw_ptr_base; hw_base = runtime->hw_ptr_base;
new_hw_ptr = hw_base + pos; new_hw_ptr = hw_base + pos;
if (in_interrupt) { if (in_interrupt) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment