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

Péter Ujfalusi
2026-03-24T07:12:13Z

On 23/03/2026 15:34, Péter Ujfalusi wrote:
> 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.

I think it worth explaining why this came up again...
In SOF we have a concept of DeepBuffer PCM devices for which in topology
one can specify the size of the host DMA buffer size (this is in the
DSP), this is where the host DMA transfers data from ALSA buffer.

side note: The DeepBuffer PCMs are not used in Linux (pipewire for
example), so no immediate need

I'm changing how it is working in a fundamental way with
https://github.com/thesofproject/linux/pull/5673
from static to dynamic allocation.

The current, static mode is really simple: in topology the DB is set to
let's say 100ms and the this is how it will be configured.
For applications I place a constraint on the minimum period size to be
100ms.
Since Pipewire does not care about period size, but it needs to provide
at least DB size of data ahead of hw_ptr we have a temporary way to use
the minimum period size as headroom:
https://gitlab.freedesktop.org/pipewire/pipewire/-/merge_requests/2548
This avoids xruns in PW and most ALSA applications also work fine.

But the change to dynamic mode will render the PW 'guessing' broken:
In dynamic mode the DB size will be configured based on the ALSA period
size, but caped at the DB value from topology. If DB was set to 100ms in
topology then this will be the maximum size of the DB, no matter how big
the ALSA period size is (see PR5673 for some numbers on how this looks),
but something like this:
ALSA period: 8 -> dma buffer: 4 ms
ALSA period: 10 -> dma buffer: 6 ms
ALSA period: 16 -> dma buffer: 12 ms
ALSA period: 19 -> dma buffer: 15 ms
ALSA period: 20 -> dma buffer: 20 ms
ALSA period: 50 -> dma buffer: 50 ms
ALSA period: 100 -> dma buffer: 100 ms
ALSA period: 150 -> dma buffer: 100 ms
ALSA period: 2000 -> dma buffer: 100 ms

Legacy applications should be fine with this, but PW still needs to
figure out the headroom andthe min period size will no longer aid that.

If we want to enable at some point the DeepBuffer PCMs for Linux via
pipewire, we need to have a way to communicate the DMA behavior.

I'm not keen on staying on the static DB as I see it as a limiting
factor. If we want a PCM with 200ms buffer (for audio playback) and we
want shallower one with 40ms for calls then you would need to have
separate PCMs and the period size would be constrained, so it is sort of
a headache for user space, while with dynamic DB you would have freedom
to use these as you wish and also benefit the power saving of the bigger
period sizes.

--
Péter