Skip to content

ALSA: compress: add mmap buffer support and SNDRV_COMPRESS_ACK ioctl - #5966

Draft
lgirdwood wants to merge 3 commits into
thesofproject:topic/sof-devfrom
lgirdwood:topic/compress-mmap
Draft

lgirdwood wants to merge 3 commits into
thesofproject:topic/sof-devfrom
lgirdwood:topic/compress-mmap

Conversation

@lgirdwood

@lgirdwood lgirdwood commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

Overview

This series adds memory-mapped (MMAP) buffer support to the ALSA compress-offload subsystem and implements the corresponding callbacks for ASoC and the Sound Open Firmware (SOF) IPC4 driver.

Currently, ALSA compressed streams only support copy-based data transfer (snd_compr_write_data() / snd_compr_read()), and snd_compr_mmap() unconditionally returns -ENXIO. For high-throughput, low-latency audio offload engines (such as hardware DSP spatial audio, voice processing, and adjacent metadata/PCM streaming in Steam Audio offload), user space needs direct, zero-copy MMAP access to the DMA buffer ring.

Alignment with Regular ALSA PCM Flow

This implementation directly mirrors the established ALSA PCM MMAP architectural pattern:

  1. Commit / Progress Notification:

    • In ALSA PCM (pcm_lib_apply_appl_ptr()), when user space writes to the mapped buffer and calls snd_pcm_mmap_commit(), the core advances appl_ptr and invokes the optional driver callback substream->ops->ack(substream).
    • In ALSA Compress, SNDRV_COMPRESS_ACK serves the exact same role: user space commits written bytes, the core advances runtime->total_bytes_available (the compress equivalent of appl_ptr), and calls stream->ops->ack(stream, bytes).
  2. Why SOF's ack is a No-Op:

    • On Intel platforms (TGL, ARL, PTL) using HDA / ACE DMA controllers, the host-to-DSP transfer is executed autonomously by hardware DMA stream descriptors from host DRAM without requiring per-transfer register doorbells or mailbox IPCs (identical to SOF PCM where ops->ack is unused / NULL).
    • In contrast, mailbox-driven DSPs (e.g. legacy Atom SST or DSPs with non-coherent SRAM) require an explicit doorbell interrupt per commit.
    • The callback is implemented as a no-op in SOF to fulfill struct snd_compress_ops, preserve subsystem symmetry with doorbell-driven platforms, and provide a hook for future platform tracing.

Summary of Changes

  1. ALSA Compress Core & UAPI (sound/core/compress_offload.c, include/uapi/sound/compress_offload.h):

    • Implement snd_compr_mmap():
      • Dispatches to stream->ops->mmap(stream, vma) when supported by the driver.
      • Falls back to snd_dma_buffer_mmap(runtime->dma_buffer_p, vma) if available.
    • Introduce SNDRV_COMPRESS_ACK ioctl (_IOW('C', 0x24, __u64)):
      • Allows user space operating in mmap mode to inform the driver of committed/consumed bytes.
      • Validates byte count against available buffer space.
      • Calls optional stream->ops->ack(stream, bytes).
      • Updates runtime->total_bytes_available.
      • Transitions state from SNDRV_PCM_STATE_SETUP to SNDRV_PCM_STATE_PREPARED on initial commit.
      • Wakes up sleeping poll/wait threads (&runtime->sleep).
  2. ASoC Compress Layer (include/sound/soc-component.h, sound/soc/soc-component.c, sound/soc/soc-compress.c):

    • Add snd_soc_component_compr_mmap() to iterate over runtime components and call component->driver->compress_ops->mmap().
    • Wire .mmap = soc_compr_mmap in both soc_compr_ops and soc_compr_dyn_ops.
  3. SOF IPC4 Compressed Driver (sound/soc/sof/ipc4-compress.c):

    • Implement sof_ipc4_compr_mmap() to map the runtime DMA buffer directly using snd_dma_buffer_mmap().
    • Implement sof_ipc4_compr_ack() callback (no-op for autonomous HDA/ACE DMA).
    • Align SOF_IPC4_COMPR_MIN_FRAGMENT_SIZE to 128 bytes to match Intel HDA / ACE DMA burst hardware constraints.
    • Register .mmap and .ack in sof_ipc4_compressed_ops.

Testing & Verification

  • Verified clean kernel build on x86_64 (sound/core/compress_offload.o, sound/soc/soc-component.o, sound/soc/soc-compress.o, sound/soc/sof/ipc4-compress.o).
  • Tested with Steam Audio adjacent MMAP and compressed stream pipelines on physical Arrow Lake hardware (Dragon Fly DUT) running kernel 7.3.0-rc1-sof-dev+.
  • All unit tests and audio loopback tests passing with zero underruns/overruns.

Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com

@lgirdwood
lgirdwood force-pushed the topic/compress-mmap branch 2 times, most recently from aca652d to 0846e93 Compare October 4, 2026 18:56
Support mapping the compressed DMA buffer to user space by implementing
snd_compr_mmap(). If the driver provides stream->ops->mmap, delegate to
it; otherwise fallback to snd_dma_buffer_mmap() on runtime->dma_buffer_p.

Introduce the SNDRV_COMPRESS_ACK ioctl (_IOW('C', 0x24, __u64)) to allow
user space to acknowledge written bytes when operating in mmap mode.
This callback directly mirrors the regular ALSA PCM mmap flow: in ALSA
PCM, user space writes to the mmap buffer and commits frames via
snd_pcm_mmap_commit(), which advances appl_ptr and invokes
substream->ops->ack(substream) via pcm_lib_apply_appl_ptr().

Similarly, for compressed streams, SNDRV_COMPRESS_ACK informs the driver
of committed bytes, validates the byte count against available buffer space,
updates runtime->total_bytes_available (analogous to advancing appl_ptr),
invokes the optional stream->ops->ack(stream, bytes) driver hook,
transitions state from SETUP to PREPARED on initial commit, and wakes up
waiters on runtime->sleep.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Add snd_soc_component_compr_mmap() to iterate over runtime components and
invoke component->driver->compress_ops->mmap() when defined.

Hook up soc_compr_mmap() in soc_compr_ops and soc_compr_dyn_ops so that
user-space mmap requests on compressed ALSA devices are routed to the
underlying ASoC component drivers.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Implement sof_ipc4_compr_mmap() to map the runtime DMA buffer
(runtime->dma_buffer_p or &stream->dma_buffer) into user space via
snd_dma_buffer_mmap().

Implement sof_ipc4_compr_ack() callback and align
SOF_IPC4_COMPR_MIN_FRAGMENT_SIZE to 128 bytes to match Intel HDA/ACE
DMA burst hardware boundaries.

For SOF on Intel HDA and ACE platforms, the host-to-DSP transfer is
driven autonomously by hardware DMA stream descriptors from host DRAM
without requiring per-block register writes or mailbox doorbells, exactly
as in standard SOF PCM where ops->ack is a no-op / NULL. The callback is
implemented as a no-op here to fulfill the struct snd_compress_ops
interface, maintain symmetry with platforms requiring doorbells/cache
flushing, and permit future platform-specific notifications.

Register .mmap and .ack in sof_ipc4_compressed_ops.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
@lgirdwood
lgirdwood force-pushed the topic/compress-mmap branch from 0846e93 to 6a16d6e Compare October 4, 2026 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants