[alsa-devel] Underrun with 2 periods on skylake HDA driver

Dharageswari R dharageswari.r at intel.com
Wed Aug 10 07:04:43 CEST 2016


Hello,

While doing the validation of Skylake HDA driver using aplay and
following parameters, we noticed underrun issues.

aplay -Dhw:0,0,0 -vv s_48K_16Bit_Sunshine.wav -F 100000 -B 200000 -d 20
Its setup is:
stream       : PLAYBACK
access       : RW_INTERLEAVED
format       : S16_LE
subformat    : STD
channels     : 2
rate         : 48000
exact rate   : 48000 (48000/1)
msbits       : 16
buffer_size  : 9600
period_size  : 4800
period_time  : 100000
tstamp_mode  : NONE
period_step  : 1
avail_min    : 4800
period_event : 0
start_threshold  : 9600
stop_threshold   : 9600
silence_threshold: 0
silence_size : 0
boundary     : 5404319552844595200
appl_ptr     : 0
hw_ptr       : 0

After doing further debugging, what I found is

1.DMA complete interrupt occurs for the first period.
2.Driver reads DMA position in buffer pointer and gets value of 4784.
3.Driver calls snd_pcm_period_elapsed() function to report period
  elapsed interrupt to application with DMA position = 4784.
4.snd_pcm_lib_write1() is waiting for “avail_min” free space to be
  available. In this case the avail_min = 4800 and at this interrupt
  the avail = 4874 and so it does not write any data.
5.DMA complete interrupt occurs for the second period.
6.Driver reads DMA position in the buffer pointer and gets value of 9600.
7.Driver calls snd_pcm_period_elapsed() function to report period 
  elapsed interrupt.
8.Now the snd_pcm_lib_write1() gets avail > avail_min but it’s too late
  because DMA has already started playing data from first period, which
  is not yet written by the application.
9.This causes underrun.

Logs:
857.870974: hwptr: pcmC0D0p/sub0: IRQ: pos=4800, old=19200, base=19200, 
period=4800, buf=9600
857.871237: hwptr: pcmC0D0p/sub0: POS: pos=4800, old=24000, base=19200, 
period=4800, buf=9600
857.970972: hwptr: pcmC0D0p/sub0: IRQ: pos=0, old=24000, base=19200, 
period=4800, buf=9600
857.971101: hwptr: pcmC0D0p/sub0: POS: pos=0, old=28800, base=28800, 
period=4800, buf=9600
858.070971: hwptr: pcmC0D0p/sub0: IRQ: pos=4784, old=28800, base=28800, 
period=4800, buf=9600
858.170968: hwptr: pcmC0D0p/sub0: IRQ: pos=0, old=33584, base=28800, 
period=4800, buf=9600
858.170988: xrun: pcmC0D0p/sub0: XRUN: old=38400, base=38400, 
period=4800, buf=9600
858.172240: hwptr: pcmC0D0p/sub0: POS: pos=96, old=0, base=0, 
period=4800, buf=9600
858.269867: hwptr: pcmC0D0p/sub0: IRQ: pos=4798, old=96, base=0, 
period=4800, buf=9600
858.369902: hwptr: pcmC0D0p/sub0: IRQ: pos=0, old=4798, base=0, 
period=4800, buf=9600

I checked with HDA architects and they are saying that when the DMA 
completion interrupt occurs there can be slight delay before the DMA 
Position In Buffer Pointer gets updated. So driver is expected to 
refill data based on whatever content is reflected in the DMA Position
In Buffer.

What is the right way to fix this issue ?

Thanks,
Dhara.R

-- 


More information about the Alsa-devel mailing list