pcm0:play:0: play interrupt timeout, channel dead

Don Lewis truckman at FreeBSD.org
Sat Sep 11 10:15:51 PDT 2004

On 11 Sep, Alexandre "Sunny" Kovalenko wrote:
> On Tue, 2004-09-07 at 22:57, Don Lewis wrote:
>> On  7 Sep, Alexandre "Sunny" Kovalenko wrote:
>> > On Tue, 2004-09-07 at 04:14, Guido van Rooij wrote:
>> >> I have this problem when using skype. Normal sound playback via e.g.
>> >> xmms goes well. This is on a Dell Latitude D600. 
>> >> 
>> >> Underneath my dmesg (witout ACPI,  with ACPI I get the same results).
>> >> 
>> >> > cat /dev/sndstat 
>> >> FreeBSD Audio Driver (newpcm)
>> >> Installed devices:
>> >> pcm0: <Intel ICH4 (82801DB)> at io 0xf4fff800, 0xf4fff400 irq 11 bufsz 16384 (1p/1r/0v channels duplex default)
>> >> 
>> >> 
>> > There is an odd looking bit of code in
>> > /usr/src/sys/dev/sound/pcm/channel.c (function chn_write):
>> > 
>> >                                 if (timeout < 1)
>> >                                         timeout = 1;
>> >                                 timeout = 1;
>> >                                 ret = chn_sleep(c, "pcmwr", timeout);
>> > 
>> > (notice that timeout is always 1).
>> > 
>> > If you feel adventurous, you can hardcode it to something like 30 and
>> > see if a) message disappears b) you get normal sound. In my case (a)
>> > happened and (b) did not -- I got distorted sound, but I was playing
>> > with USB audio device, which has features not supported by the driver.
>> This has been discussed before on the list.  The statement immediately
>> before the code fragment that you posted sets timeout to a dynamically
>> determined value based on the buffer size and sample rate.  The 'if'
>> block forces the timeout to be non-zero if the calculation results in a
>> zero timeout.  Somewhere along the way, someone added the statement to
>> unconditionally force timeout to 1, most likely to minimize the chance
>> for skipping or distortion if a wakeup() was missed.  The will cause the
>> 'while' loop to burn a bit more CPU time because it is essentially
>> running in a polled mode.
>> The ich problem appears to be located in ich_intr().  This
>> hardware-specific interrupt handler does not appear to be seeing the
>> correct bits in the hardware registers that are supposed to tell it that
>> an interrupt has occurred in the hardware play channel.
>> The "play interrupt timeout, channel dead" message will occur if there
>> isn't at least one play channel interrupt per second.
> FWIW: I have received this message when dealing with USB audio (uaudio
> driver). Increasing constant eliminated the message. I do not know
> enough about audio handling to speculate any further.

Are you using a non-default value of HZ in your kernel config file?

I don't see any reason why the code should behave differently with the
default value of HZ (100) if timeout is set to 1 versus 30.  In the
first case, the code will sleep 100 times for one tick each time before
count reaches zero and the channel is marked as dead.  In the second
case the code will sleep four times and decrement count by 30 each time
before count goes negative.  What happens if you set timeout to 33? What
about 34?  What happens if the two places that set 'count = hz' are
changed to 'count = 2 * hz'?

Now that chn_sleep() uses msleep(), it should be possible to set timeout
to 0, which would give an indefinite wait.  If the channel dies, the
application will hang, but the application should be killable.  It
should also be possible to set timeout to hz.

More information about the freebsd-current mailing list