Skip to content

audio: dai-zephyr: enable user-space use of DAI #10801

Draft
kv2019i wants to merge 7 commits into
thesofproject:mainfrom
kv2019i:202605-host-dai-user
Draft

audio: dai-zephyr: enable user-space use of DAI #10801
kv2019i wants to merge 7 commits into
thesofproject:mainfrom
kv2019i:202605-host-dai-user

Conversation

@kv2019i
Copy link
Copy Markdown
Collaborator

@kv2019i kv2019i commented May 21, 2026

A series of of patches to enable dai-zephyr component to be used in user-space. This includes:

  • addition of new sof_umutex.h rtos interface that is used to implement DAI property locking (instead of spinlocks)
  • fixes to sof_dma.h (ability to use SG lists with loops)
  • make dai_get() work in user-space
  • fix use of dai_get_properties() to be safe to be used from user-space
  • modify heap allocations in dai-zephyr so that they will work also when building for user-space LL

Similar changes to host-zephyr are in #10799

kv2019i added 7 commits May 21, 2026 21:14
Allow a non-null pointer at the end of the DMA transfer block list,
if and only if it points to the first entry in the block list.

The SOF DAI module sets the DMA transfers blocks like this and
this change is required to use DAI module from user-space.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
The dai_get()/dai_put() provide a helper to access DAI devices.
When used in user-space, the wrapper struct should be created in
user-space memory.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Modify code to allocate DAI properties object on stack and
use dai_get_properties_copy(). This is required when DAI code
is run in user-space and a syscall is needed to talk to the DAI
driver. It's not possible to return a pointer to kernel memory,
so instead data needs to be copied to caller stack.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
The Zephyr locking interfaces do not have a variant that allows the lock
object to be put in dynamically allocated user-space memory. Implement a
variant on top of Zephyr k_mutex that provides this support for SOF.
Provide a no-op wrapper for POSIX library builds (just like we do for
other locking interfaces).

Kconfig option SOF_USERSPACE_INTERFACE_MUTEX is added to control
whether umutex.h is exposed to user-space or not.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
The spinlock used to protect access to DAI properties can be
converted to a sof_umutex as this is only accessed from IPC and LL threads
and both are normal Zephyr threads. As an additional benefit, use
of sof_umutex allows to run the dai-zephyr module in user-space.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reorder redefinitions to ensure "struct mod_alloc_ctx" is defined
before lib/dai.h is included.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Convert all memory allocations to use the sof_heap_alloc() interface
and pass the dai_data specific heap object. This makes dai-zephyr
code compatible with use from user-space, but does not affect
kernel space use.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Copilot AI review requested due to automatic review settings May 21, 2026 18:22
@kv2019i kv2019i requested a review from jsarha May 21, 2026 18:22
@kv2019i
Copy link
Copy Markdown
Collaborator Author

kv2019i commented May 21, 2026

For context, part of #10558

Comment thread zephyr/Kconfig
depends on USERSPACE
help
Allow user-space threads to use sof_heap_alloc/sof_heap_free
as Zephyr system calls.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, this ALLOC is a stray commit, will remove in V2.

)
if(CONFIG_USERSPACE AND CONFIG_SOF_USERSPACE_INTERFACE_ALLOC)
zephyr_library_sources(userspace/test_heap_alloc.c)
endif()
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And another stray bit for test_heap_alloc.c. Will remove in V2.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enables the dai-zephyr component (and related infrastructure) to be usable from Zephyr user-space threads by introducing a user-space mutex abstraction, updating syscall verification, and adjusting allocations to work with user-space heaps/memory domains.

Changes:

  • Add sof_umutex API (Zephyr + POSIX) with syscall plumbing and a user-space test.
  • Update dai-zephyr to use sof_umutex for property protection and to use heap-aware allocation/free paths.
  • Update the SOF DMA syscall deep-copy logic to support cyclic (looping) SG block lists.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
zephyr/test/userspace/test_umutex.c Adds a user-space thread test for sof_umutex init/lock/unlock/free.
zephyr/test/CMakeLists.txt Wires new user-space tests into the Zephyr test build.
zephyr/syscall/umutex.c Adds syscall verification handlers for sof_umutex_*.
zephyr/syscall/sof_dma.c Extends DMA block list deep-copy to allow looping SG lists.
zephyr/lib/umutex.c Implements kernel-side sof_umutex using dynamically allocated k_mutex.
zephyr/Kconfig Introduces Kconfig switches for userspace alloc + mutex interfaces and selects mutex for userspace LL.
zephyr/include/rtos/umutex.h Declares the sof_umutex API and syscall wrappers.
zephyr/include/rtos/mutex.h Exposes sof_umutex via the RTOS mutex umbrella header.
zephyr/CMakeLists.txt Adds umutex implementation and syscall sources/headers to the Zephyr build.
src/lib/dai.c Updates dai_get()/dai_put() allocation/free to use sof_heap_alloc/free (userspace LL aware).
src/ipc/ipc4/dai.c Uses heap-aware allocation/free for dd->dai_spec_config.
src/include/sof/lib/dai-zephyr.h Switches DAI property lock to sof_umutex and adds mod_alloc_ctx to dai_data.
src/include/sof/audio/component.h Moves mod_alloc_ctx definition earlier to satisfy DAI header needs.
src/audio/dai-zephyr.c Replaces spinlock-based property protection with sof_umutex and updates multiple allocations to use alloc_ctx.heap.
posix/include/rtos/umutex.h Adds POSIX header wrapper for sof_umutex.
posix/include/rtos/mutex.h Adds a POSIX stub implementation of sof_umutex.

Comment on lines +11 to +13
if(CONFIG_USERSPACE AND CONFIG_SOF_USERSPACE_INTERFACE_ALLOC)
zephyr_library_sources(userspace/test_heap_alloc.c)
endif()
Comment thread zephyr/syscall/umutex.c
Comment on lines +23 to +41
static inline int z_vrfy_sof_umutex_lock(struct sof_umutex *umutex,
k_timeout_t timeout)
{
K_OOPS(K_SYSCALL_MEMORY_WRITE(umutex, sizeof(struct sof_umutex)));
return z_impl_sof_umutex_lock(umutex, timeout);
}
#include <zephyr/syscalls/sof_umutex_lock_mrsh.c>

static inline int z_vrfy_sof_umutex_unlock(struct sof_umutex *umutex)
{
K_OOPS(K_SYSCALL_MEMORY_WRITE(umutex, sizeof(struct sof_umutex)));
return z_impl_sof_umutex_unlock(umutex);
}
#include <zephyr/syscalls/sof_umutex_unlock_mrsh.c>

static inline void z_vrfy_sof_umutex_free(struct sof_umutex *umutex)
{
K_OOPS(K_SYSCALL_MEMORY_WRITE(umutex, sizeof(struct sof_umutex)));
z_impl_sof_umutex_free(umutex);
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a valid concern. The verification is similar to zephyr sys_mutex() but it has additional step to look up the k_object() that is not here. Let me mark as draft to ensure this is addressed before merge.

Comment thread zephyr/syscall/umutex.c
Comment on lines +26 to +33
K_OOPS(K_SYSCALL_MEMORY_WRITE(umutex, sizeof(struct sof_umutex)));
return z_impl_sof_umutex_lock(umutex, timeout);
}
#include <zephyr/syscalls/sof_umutex_lock_mrsh.c>

static inline int z_vrfy_sof_umutex_unlock(struct sof_umutex *umutex)
{
K_OOPS(K_SYSCALL_MEMORY_WRITE(umutex, sizeof(struct sof_umutex)));
Comment thread zephyr/lib/umutex.c
Comment on lines +18 to +35
int z_impl_sof_umutex_init(struct sof_umutex *umutex)
{
struct k_mutex *m;
int ret;

m = k_object_alloc(K_OBJ_MUTEX);
if (m == NULL) {
return -ENOMEM;
}

ret = k_mutex_init(m);
if (ret) {
k_object_free(m);
return ret;
}

umutex->mutex = m;
return 0;
Comment thread src/audio/dai-zephyr.c
Comment on lines 226 to +235
/* called from ipc/ipc3/dai.c */
int dai_get_handshake(struct dai *dai, int direction, int stream_id)
{
k_spinlock_key_t key = k_spin_lock(&dai->lock);
const struct dai_properties *props = dai_get_properties(dai->dev, direction,
stream_id);
int hs_id = props->dma_hs_id;
struct dai_properties props;
int ret;

k_spin_unlock(&dai->lock, key);
sof_umutex_lock(&dai->lock, K_FOREVER);
ret = dai_get_properties_copy(dai->dev, direction, stream_id, &props);
sof_umutex_unlock(&dai->lock);
if (ret < 0)
Comment thread src/audio/dai-zephyr.c
dd->dma_buffer = NULL;
dma_sg_free(NULL, &config->elem_array);
rfree(dd->z_config);
dma_sg_free(dd->alloc_ctx.heap, &config->elem_array);
@kv2019i kv2019i marked this pull request as draft May 21, 2026 18:44
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