Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SOF driver should report maximum DMA burst size to user-space via an ALSA interface #5313

Open
kv2019i opened this issue Jan 29, 2025 · 14 comments
Labels
enhancement New feature or request

Comments

@kv2019i
Copy link
Collaborator

kv2019i commented Jan 29, 2025

SOF sound devices can support large audio buffers, allowing audio playback/capture to continue without waking up the host CPU and memory as often and thus save power.

For ALSA applications, this shows up as bursty updates to the ALSA hw_ptr. Many/most applications can cope with this without issues, but some applications that assume hw_ptr advances linearly, this creates problems. [1, 2]. Probably most mainstream case is Pipewire when it decides how much data it needs to fill before starting a stream (or after an xrun). If the amount of data is smaller or close to the size of the max DMA burst, xruns or even xrun loops (repeated error to start with too little data) can be hit as audio device consumes all audio data before Pipewire has a chance to provide more data.

The amount of buffering depends on the hardware and the DSP topology/configuration. For a typical SOF PCM, maximum burst size is a few milliseconds, but there are DSP topologies where the maximum burst size can be in tens of milliseconds.

There is currently no established interface in ALSA for drivers to communicate the maximum burst size. Existing interfaces are surveyed in [2]. snd_pcm_hw_params_is_block_transfer() is probably the closest match, but it does not provide enough information about size of the burst.

Proposal is to extend ALSA driver and alsa-lib interface to make this information available to applications like Pipewire.

Alternatives to consider:

  • SOF could declare SNDRV_PCM_INFO_BATCH. SOF has not set this a) would disable features in applications like Pipewire, and b) SOF can deliver accurate hw_ptr location (even during bursts).
  • add a new info flag SNDRV_PCM_INFO_BURSTY_DMA. this would be overlapping with existing BLOCK_TRANSFER/BATCH flags and still not provide enough information to applications to fully understand driver behaviour.
  • add an attribute to UCM -- easier to add, but the burst size can vary based on topology and hw, so maintaining correct information in UCM will be a challenge

References:

@kv2019i kv2019i added the enhancement New feature or request label Jan 29, 2025
@kv2019i
Copy link
Collaborator Author

kv2019i commented Jan 29, 2025

FYI @ujfalusi @lgirdwood @ford-prefect

@ujfalusi
Copy link
Collaborator

ujfalusi commented Jan 29, 2025

@kv2019i, fwiw, PW/PA have exception for USB audio, which declares SNDRV_PCM_INFO_BATCH. It acknowledges this, but still enables the features that are blocked for other PCM devices.
We could in theory do the same for SOF, but the SNDRV_PCM_INFO_BATCH says that the pointer resolution is limited to period size and that is not true for SOF, we can report accurate DMA position (and with IPC4 we can also report delay), we just have jumpy DMA.

@ford-prefect
Copy link

@ujfalusi fwiw, the exception for USB devices is not present in PipeWire.

@ujfalusi
Copy link
Collaborator

@ford-prefect
Copy link

ford-prefect commented Jan 29, 2025

@ujfalusi I believe that code is only used while probing (in fact, only while probing the Pro Audio profile). The code for actually using the PCM is at https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/spa/plugins/alsa/alsa-pcm.c#L2025 (ironically, in Pro Audio mode, we don't use timer-based scheduling at all, which means the headroom/BATCH flag doesn't kick in)

@ujfalusi
Copy link
Collaborator

@ford-prefect, interesting. When I tried out of curiosity to set the BATCH for SOF then PW disabled tsched for non Pro audio as well.
I changed this check to a constructive if (1) and tsched was back with the other niceties to set the deadline a bit further from the hw_ptr.

But I don't know the PW (or PA) code at all, I was just blindly hacking...

@ford-prefect
Copy link

@ujfalusi that's odd, I don't see any reason BATCH should cause tsched to be disabled (verified with my USB device here). Might be worth an upstream bug (with some PIPEWIRE_DEBUG=3 logs and pw-dump output).

@ujfalusi
Copy link
Collaborator

USB is special cased to allow tsched even if it reports BATCH.

@ford-prefect
Copy link

In my case, it uses tsched even if I disable the is_usb check in alsa-util.c -- which is what I expect based on the code. Just to sanity check, how do you verify that PW is using tsched vs. not?

@ujfalusi
Copy link
Collaborator

Hrm, re-reading the code and I'm not sure anymore, but looks like that tsched is always enabled and can only be disabled with a config parameter?
state->disable_tsched via api.alsa.disable-tsched

The other issue with BATCH is that it causes the period_wakes not to be disabled, which we don't want, that I hope I read right...
https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/spa/plugins/alsa/alsa-pcm.c?ref_type=heads#L2306

I'm a bit confused around the pa_alsa_set_hw_params(), but that looks to be a distraction

@ford-prefect
Copy link

ford-prefect commented Jan 30, 2025

That's mostly correct: tsched is disabled for pro-audio devices, or if explicitly configured. And yes, you also read the thing about not disabling period interrupts correctly -- I'm not sure that's actually required, but maybe @wtay knows?

@wtay
Copy link

wtay commented Jan 30, 2025

maybe @wtay knows?

What do I know... I kept the interrupts enabled because I thought they are used to update the ringbuffer read and write pointers.

@ford-prefect
Copy link

@wtay ah! yes, I do think we've seen that in the past in PulseAudio.

@plbossart
Copy link
Member

Shouldn't apps looks at the 'delay' and not just the hw_ptr? The information is already reported by the 'status' ALSA API. Is there a need to invent something new?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants