[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-sound
Subject: write hanging in i810_audio
From: Steve Fink <sfink () reactrix ! com>
Date: 2005-05-04 18:06:33
Message-ID: 42790F29.6060301 () reactrix ! com
[Download RAW message or body]
I have half a dozen boxes running Linux, and I'm using esd for audio.
Three of them have, after running for a day or two, gotten into a state
where esd is hung. strace shows that it is in a blocking write to
/dev/dsp. I am using the OSS drivers. /dev/dsp is handled by the
i810_audio module. Alt-SysRq-T shows this stack trace:
kernel: SysRq : Show State
kernel:
kernel: free sibling
kernel: task PC stack pid father child younger older
kernel: esd S E89FC000 0 6531 6529
(NOTLB)
kernel: Call Trace: [<c011d5e5>] schedule [kernel] 0x125 (0xe89fdec0)
kernel: [<c012bb35>] schedule_timeout [kernel] 0x65 (0xe89fdee0)
kernel: [<c012bac0>] process_timeout [kernel] 0x0 (0xe89fdf00)
kernel: [<f89b39ff>] i810_write [i810_audio] 0x2df (0xe89fdf18)
kernel: [<c0153a53>] sys_write [kernel] 0xa3 (0xe89fdf94)
What's the easiest way to disassemble a chunk of kernel memory while
you're running? I ended up writing a perl script using Disassemble::X86
for disassembling a chunk of /proc/kcore to track down the address
within i810_write, along with the running kernel's System.map and
/proc/ksyms and `nm i180_audio.o` to resolve the symbols. Surely there's
an easier way?
Anyway, the relevant portion of the disassembly is below. It allowed me
to track down the source location to the schedule_timeout() in
i810_audio.c here:
dmabuf->trigger = PCM_ENABLE_OUTPUT;
i810_update_lvi(state,0);
if (file->f_flags & O_NONBLOCK) {
if (!ret) ret = -EAGAIN;
goto ret;
}
/* Not strictly correct but works */
tmo = (dmabuf->dmasize * HZ * 2) / (dmabuf->rate * 4);
/* There are two situations when sleep_on_timeout returns,
one is when the interrupt is serviced correctly and the
process is waked up by ISR ON TIME. Another is when
timeout is expired, which means that either interrupt is
NOT serviced correctly (pending interrupt) or it
is TOO LATE for the process to be scheduled to run
(scheduler latency) which results in a (potential) buffer
underrun. And worse, there is NOTHING we can do to prevent it. */
if (!schedule_timeout(tmo >= 2 ? tmo : 2)) {
#ifdef DEBUG
printk(KERN_ERR "i810_audio: playback schedule timeout, "
"dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
dmabuf->hwptr, dmabuf->swptr);
#endif
/* a buffer underrun, we delay the recovery until next time the
while loop begin and we REALLY have data to play */
//return ret;
}
I'm way out of my depth here, but it seems like it's expecting a DMA
transfer to come back and it never does.
First, is this a known problem? Second, how could I go about debugging
this further? I don't have a reliable way of reproducing the problem, so
I'm interested in ways of diagnosing the running system in its hung
state. Can I dump out the state of active DMA requests somehow? What's
the easiest way to see the registers for this stack frame (or for this
execution context, at least)?
The disassembly of the relevant chunk of kernel memory around the
i180_write stack frame is here:
f89b39ce mov eax,dword[esi+0x40]
f89b39d1 lea eax,[eax+eax*4]
f89b39d4 lea eax,[eax+eax*4]
f89b39d7 lea edx,[eax*8+0x0]
f89b39af nop
f89b39b0* mov byte[esi+0x6],0x2 (from f89b3929)
f89b39b4 mov dword[ss:esp+0x4],0x0
f89b39bc mov dword[ss:esp],ebx
f89b39bf call 0xf89b2d20 (i810_update_lvi)
f89b39c4 mov edi,dword[ss:esp+0x7c]
f89b39c8 test byte[edi+0x19],0x8
f89b39af nop
f89b39b0* mov byte[esi+0x6],0x2 (from f89b3929)
f89b39b4 mov dword[ss:esp+0x4],0x0
f89b39bc mov dword[ss:esp],ebx
f89b39bf call 0xf89b2d20 (i810_update_lvi)
f89b39c4 mov edi,dword[ss:esp+0x7c]
f89b39c8 test byte[edi+0x19],0x8
f89b39cc jne 0xf89b3a27 (i810_write+0x307)
f89b39ce mov eax,dword[esi+0x40]
f89b39d1 lea eax,[eax+eax*4]
f89b39d4 lea eax,[eax+eax*4]
f89b39d7 lea edx,[eax*8+0x0]
f89b39de mov eax,dword[esi]
f89b39e0 lea ecx,[eax*4+0x0]
f89b39e7 mov eax,edx
f89b39e9 xor edx,edx
f89b39eb div ecx
f89b39ed mov ecx,eax
f89b39ef mov eax,0x2
f89b39f4 cmp ecx,0x1
f89b39f7 cmova eax,ecx
f89b39fa call 0xc012bad0 (schedule_timeout)
f89b39ff mov edx,dword[ss:esp+0x14]
I am running RedHat's 2.4.21-20.EL kernel on an ICH5 board.
-
To unsubscribe from this list: send the line "unsubscribe linux-sound" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic