Hi,
The size of the DSP host buffer was incorrectly defined as 2ms while it is 4ms and the ChainDMA PCMs are using 5ms as host facing buffer.
The constraint will be set against the period time rather than the buffer time to make sure that application will not face with xruns when the DMA bursts to refill the host buffer.
The minimal period size will be also used by Pipewire in case of SOF cards to set the headroom to a length which will avoid the cases when the hw_ptr jumps over the appl_ptr because of a burst. Iow, it will make Pipewire to keep a safe distance from the hw_ptr.
https://github.com/thesofproject/linux/issues/5284 https://gitlab.freedesktop.org/pipewire/wireplumber/-/merge_requests/740 https://gitlab.freedesktop.org/pipewire/pipewire/-/merge_requests/2548
Regards, Peter --- Peter Ujfalusi (3): ASoC: SOF: ipc4-topology: Correct the minimum host DMA buffer size ASoC: SOF: ipc4-topology: Account for different ChainDMA host buffer size ASoC: SOF: Intel: hda-pcm: Place the constraint on period time instead of buffer time
sound/soc/sof/intel/hda-pcm.c | 29 +++++++++++++++++++++-------- sound/soc/sof/ipc4-topology.c | 9 +++++++-- sound/soc/sof/ipc4-topology.h | 7 +++++-- 3 files changed, 33 insertions(+), 12 deletions(-)
The firmware has changed the minimum host buffer size from 2 periods to 4 periods (1 period is 1ms) which was missed by the kernel side.
Adjust the SOF_IPC4_MIN_DMA_BUFFER_SIZE to 4 ms to align with firmware.
Cc: stable@vger.kernel.org Link: https://github.com/thesofproject/sof/commit/f0a14a3f410735db18a79eb7a5f40dc4... Fixes: a2db53360203 ("ASoC: SOF: ipc4-topology: Do not parse the DMA_BUFFER_SIZE token") Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/sof/ipc4-topology.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h index dfa1a6c2ffa8..d6894fdd7e1d 100644 --- a/sound/soc/sof/ipc4-topology.h +++ b/sound/soc/sof/ipc4-topology.h @@ -70,8 +70,8 @@ #define SOF_IPC4_CHAIN_DMA_NODE_ID 0x7fffffff #define SOF_IPC4_INVALID_NODE_ID 0xffffffff
-/* FW requires minimum 2ms DMA buffer size */ -#define SOF_IPC4_MIN_DMA_BUFFER_SIZE 2 +/* FW requires minimum 4ms DMA buffer size */ +#define SOF_IPC4_MIN_DMA_BUFFER_SIZE 4
/* * The base of multi-gateways. Multi-gateways addressing starts from
For ChainDMA the firmware allocates 5ms host buffer instead of the standard 4ms which should be taken into account when setting the constraint on the buffer size.
Cc: stable@vger.kernel.org Fixes: 72af064faead ("ASoC: SOF: ipc4-topology: Save the DMA maximum burst size for PCMs") Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/sof/ipc4-topology.c | 9 +++++++-- sound/soc/sof/ipc4-topology.h | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index b6a732d0adb4..60cd7955e24f 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -666,8 +666,13 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget) swidget->tuples, swidget->num_tuples, sizeof(u32), 1); /* Set default DMA buffer size if it is not specified in topology */ - if (!sps->dsp_max_burst_size_in_ms) - sps->dsp_max_burst_size_in_ms = SOF_IPC4_MIN_DMA_BUFFER_SIZE; + if (!sps->dsp_max_burst_size_in_ms) { + struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; + struct sof_ipc4_pipeline *pipeline = pipe_widget->private; + + sps->dsp_max_burst_size_in_ms = pipeline->use_chain_dma ? + SOF_IPC4_CHAIN_DMA_BUFFER_SIZE : SOF_IPC4_MIN_DMA_BUFFER_SIZE; + } } else { /* Capture data is copied from DSP to host in 1ms bursts */ spcm->stream[dir].dsp_max_burst_size_in_ms = 1; diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h index d6894fdd7e1d..fc3b6411b9b2 100644 --- a/sound/soc/sof/ipc4-topology.h +++ b/sound/soc/sof/ipc4-topology.h @@ -73,6 +73,9 @@ /* FW requires minimum 4ms DMA buffer size */ #define SOF_IPC4_MIN_DMA_BUFFER_SIZE 4
+/* ChainDMA in fw uses 5ms DMA buffer */ +#define SOF_IPC4_CHAIN_DMA_BUFFER_SIZE 5 + /* * The base of multi-gateways. Multi-gateways addressing starts from * ALH_MULTI_GTW_BASE and there are ALH_MULTI_GTW_COUNT multi-sources
Instead of constraining the ALSA buffer time to be double of the firmware host buffer size, it is better to set it for the period time. This will implicitly constrain the buffer time to a safe value (num_periods is at least 2) and prohibits applications to set smaller period size than what will be covered by the initial DMA burst.
Cc: stable@vger.kernel.org Fixes: 02ea2a0364a2 ("ASoC: SOF: Intel: hda-pcm: Use dsp_max_burst_size_in_ms to place constraint") Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/sof/intel/hda-pcm.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c index 1dd8d2092c3b..da6c1e7263cd 100644 --- a/sound/soc/sof/intel/hda-pcm.c +++ b/sound/soc/sof/intel/hda-pcm.c @@ -29,6 +29,8 @@ #define SDnFMT_BITS(x) ((x) << 4) #define SDnFMT_CHAN(x) ((x) << 0)
+#define HDA_MAX_PERIOD_TIME_HEADROOM 10 + static bool hda_always_enable_dmi_l1; module_param_named(always_enable_dmi_l1, hda_always_enable_dmi_l1, bool, 0444); MODULE_PARM_DESC(always_enable_dmi_l1, "SOF HDA always enable DMI l1"); @@ -291,19 +293,30 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev, * On playback start the DMA will transfer dsp_max_burst_size_in_ms * amount of data in one initial burst to fill up the host DMA buffer. * Consequent DMA burst sizes are shorter and their length can vary. - * To make sure that userspace allocate large enough ALSA buffer we need - * to place a constraint on the buffer time. + * To avoid immediate xrun by the initial burst we need to place + * constraint on the period size (via PERIOD_TIME) to cover the size of + * the host buffer. + * We need to add headroom of max 10ms as the firmware needs time to + * settle to the 1ms pacing and initially it can run faster for few + * internal periods. * * On capture the DMA will transfer 1ms chunks. - * - * Exact dsp_max_burst_size_in_ms constraint is racy, so set the - * constraint to a minimum of 2x dsp_max_burst_size_in_ms. */ - if (spcm->stream[direction].dsp_max_burst_size_in_ms) + if (spcm->stream[direction].dsp_max_burst_size_in_ms) { + unsigned int period_time = spcm->stream[direction].dsp_max_burst_size_in_ms; + + /* + * add headroom over the maximum burst size to cover the time + * needed for the DMA pace to settle. + * Limit the headroom time to HDA_MAX_PERIOD_TIME_HEADROOM + */ + period_time += min(period_time, HDA_MAX_PERIOD_TIME_HEADROOM); + snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_BUFFER_TIME, - spcm->stream[direction].dsp_max_burst_size_in_ms * USEC_PER_MSEC * 2, + SNDRV_PCM_HW_PARAM_PERIOD_TIME, + period_time * USEC_PER_MSEC, UINT_MAX); + }
/* binding pcm substream to hda stream */ substream->runtime->private_data = &dsp_stream->hstream;
On 02/10/2025 15:25, Mark Brown wrote:
On Thu, Oct 02, 2025 at 11:05:35AM +0300, Peter Ujfalusi wrote:
Hi,
The size of the DSP host buffer was incorrectly defined as 2ms while it is 4ms and the ChainDMA PCMs are using 5ms as host facing buffer.
None of the fixes tags in this series point to commits in my tree.
Hrm, they are upstream, I will check and resend, sorry
On Thu, 02 Oct 2025 11:05:35 +0300, Peter Ujfalusi wrote:
The size of the DSP host buffer was incorrectly defined as 2ms while it is 4ms and the ChainDMA PCMs are using 5ms as host facing buffer.
The constraint will be set against the period time rather than the buffer time to make sure that application will not face with xruns when the DMA bursts to refill the host buffer.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/3] ASoC: SOF: ipc4-topology: Correct the minimum host DMA buffer size commit: a7fe5ff832d61d9393095bc3dd5f06f4af7da3c1 [2/3] ASoC: SOF: ipc4-topology: Account for different ChainDMA host buffer size commit: 3dcf683bf1062d69014fe81b90d285c7eb85ca8a [3/3] ASoC: SOF: Intel: hda-pcm: Place the constraint on period time instead of buffer time commit: 45ad27d9a6f7c620d8bbc80be3bab1faf37dfa0a
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
linux-stable-mirror@lists.linaro.org