(re)use and (re)definition of snd_pcm_hw_params->fifo_size for 'jumpy DMA'

Péter Ujfalusi
2026-03-23T13:34:55Z

Hi,

for years the discussion around jumpy, bursty DMA have been popping up
and we always concluded that we are missing a good definition and agreed
way between kernel and user space to handle this.

In ALSA it is expected that the DMA (hw_ptr) moves in steady small
steps. There is a BATCH mode which tells that the DMA cannot report sub
period size position, progression.
The DMA bursting fits neither of this, it moves in bigger jumps (bursts)
and it can as well can report position in byte level.

Typically these systems have DSP which can consumes data in various
chunks, making the hw_ptr to jump. Over time the hw_ptr do move at the
sampling rate, but when zooming in we can see:
initial jump of X frames, hw_ptr stays static for about ~X frame worth
of time then the hw_ptr jumps again ahead of X frames, and again, hw_ptr
stops, ...

This can be a problem for user space which wants to write samples as
close to hw_ptr as possible since if it is not aware of the bursty-DMA
than it is possible that a burst will jump over the sw_ptr, causing xrun.

I was looking at what, how and where we should add this information in
kernel and to take it in use by user space when I stumbled across the
'fifo_size' of hw_params struct.

It is only set by a few drivers:
sound/arm/aaci.c
sound/arm/pxa2xx-pcm-lib.c
sound/soc/renesas/dma-sh7760.c
sound/soc/starfive/jh7110_tdm.c
sound/soc/tegra/tegra_pcm.c
sound/soc/xtensa/xtfpga-i2s.c
sound/usb/misc/ua101.c
sound/x86/intel_hdmi_audio.c

It's definition is awkwardly a bit different in kernel and alsa-lib:
in kernel it can be in bytes or frames, but in user space it is always
in frames (snd_pcm_hw_params_get_fifo_size).

So far I could not find evidence that this is in active use by user
space. Not used in alsa-utils, pipewire, pulseaudio at least and web
search came back empty handed as well.

My proposal thus is to re-use, re-define extend the fifo_size as and
indication that the hw_ptr _can_ jump at least fifo_size number of
frames so applications must take this into account when doing direct
update in ALSA buffer for low latency.

Or should we add a new member (carved out from the reserved section of
hw_params struct) specifically for this purpose, like dma_burst_size,
which likely going to be equal to fifo_size if both is filled by the driver.

Or a new flag (SNDRV_PCM_INFO_) that PCM devices can use to indicate
that the DMA is bursting and in that case the fifo_size holds the number
of frames that it is expected to jump.
But we are slowly running out of bits and I'm not sure if it is a good
idea to dual use in kernel internal bits for user ABI
(SNDRV_PCM_INFO_DRAIN_TRIGGER, SNDRV_PCM_INFO_FIFO_IN_FRAMES)

https://github.com/thesofproject/linux/issues/5313
https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4489

--
Péter