[DRAFT] userspace LL/audio test PR#10558
[DRAFT] userspace LL/audio test PR#10558kv2019i wants to merge 112 commits intothesofproject:mainfrom
Conversation
|
Running the pipeline_two_components_user test added in this PR, on a Intel PTL, looks like this: |
9cdb1be to
37b0412
Compare
|
V2 snapshot pushed:
|
37b0412 to
7317b18
Compare
|
V3 snapshot pushed:
|
|
Test output for the new test added in V3: |
| /* works? yes */ | ||
| //return 0; | ||
|
|
||
| printk("ipc %p\n", ipc); |
There was a problem hiding this comment.
Oops, these shouldn't be here. :)
|
|
||
| /* create the pipeline */ | ||
| pipe = pipeline_new(NULL, pipe_desc->primary.r.instance_id, | ||
| pipe = pipeline_new(heap, pipe_desc->primary.r.instance_id, |
There was a problem hiding this comment.
@lyakh @jsarha @lgirdwood This is where you'd plug in the vregions stuff to pass a separate heap to each pipe (based on topology description of its needs). In this series, as a placeholder, I use the zephyr_ll_user_heap() instead.
There was a problem hiding this comment.
right, maybe put a comment there for now to make re-discovery easier
lyakh
left a comment
There was a problem hiding this comment.
last reviewed commit so far "schedule: zephyr_ll: implement thread_init/free domain ops"
| #ifdef CONFIG_SOF_USERSPACE_LL | ||
| void comp_grant_access_to_thread(const struct comp_dev *dev, struct k_thread *th) | ||
| { | ||
| assert(dev->list_mutex); |
There was a problem hiding this comment.
description a bit confusing - this is only granting access to a mutex. Also list_mutex is only added to comp_dev in the next commit.
| } | ||
|
|
||
| stream_addr = rballoc_align(flags, size, align); | ||
| stream_addr = sof_heap_alloc(heap, flags, size, align); |
There was a problem hiding this comment.
the commit, that is mentioned in the commit message, only moved buffer context objects to particular heaps. This commit moves actual data buffers to them too, which is different and (arguably) more risky
| #define HDA_DMA_BUFFER_PERIOD_COUNT 4 | ||
|
|
||
| SHARED_DATA struct sof_dma dma[] = { | ||
| APP_TASK_DATA SHARED_DATA struct sof_dma dma[] = { |
There was a problem hiding this comment.
do I understand correctly, that this kind of userspace access makes that data writable to userspace?
| comp_err(dev, "requested channel %d is busy", hda_chan); | ||
| return -ENODEV; | ||
| } | ||
| hd->chan = &hd->dma->chan[channel]; |
There was a problem hiding this comment.
is this also not needed for the legacy mode? Also below
| uint64_t next_sync; | ||
| uint64_t period_in_cycles; | ||
| #endif | ||
| struct k_heap *heap; |
There was a problem hiding this comment.
wasn't this already referenced in the previous commit?
|
|
||
| k_spinlock_init(&dd->dai->lock); | ||
| #ifdef CONFIG_SOF_USERSPACE_LL | ||
| dd->dai->lock = k_object_alloc(K_OBJ_MUTEX); |
There was a problem hiding this comment.
check for NULL? Possibly in other locations too
| k_mutex_lock(dai->lock, K_FOREVER); | ||
| props = dai_get_properties(dai->dev, direction, stream_id); | ||
| hs_id = props->dma_hs_id; | ||
| ret = dai_get_properties_copy(dai->dev, direction, stream_id, &props); |
There was a problem hiding this comment.
I'm guessing this is made a syscall in one of the commits
| mod_heap = &mod_heap_user->heap; | ||
| } else { | ||
| #ifdef CONFIG_SOF_USERSPACE_LL | ||
| mod_heap = zephyr_ll_user_heap(); |
There was a problem hiding this comment.
looks good, but this else is entered under multiple conditions, might need to double-check
| .schedule_task_before = zephyr_ll_task_schedule_before, | ||
| .schedule_task_after = zephyr_ll_task_schedule_after, | ||
| .schedule_task_free = zephyr_ll_task_free, | ||
| .schedule_task_free = zephyr_ll_task_sched_free, |
There was a problem hiding this comment.
let's "spend" 3 more characters and make it ..._schedule_free()
| return -ENOMEM; | ||
| } | ||
| tr_err(&ll_tr, "Failed to allocate thread object for core %d", core); | ||
| dt->handler = NULL; |
| { | ||
| const struct sof_man_fw_desc *desc = basefw_vendor_get_manifest(); | ||
| const struct sof_man_module *mod; | ||
| uint32_t i; |
| uint32_t i; | ||
|
|
||
| if (!desc) | ||
| return -1; |
| return (int)i; | ||
| } | ||
|
|
||
| return -1; |
| union ipc4_connector_node_id node_id; | ||
| uint32_t dma_buffer_size; | ||
| uint32_t config_length; | ||
| } __packed __aligned(4); |
There was a problem hiding this comment.
does __aligned actually make sense in a type definition?
| pipe_msg.extension.dat = ipc_user->ipc_msg_ext; | ||
|
|
||
| /* Execute pipeline creation in user context */ | ||
| ipc_user->result = ipc_pipeline_new(ipc_user->ipc, (ipc_pipe_new *)&pipe_msg); |
There was a problem hiding this comment.
that's brave! ;-) I'd put a huge "TODO" here to make sure not to ship this by chance :-)
|
|
||
| /* create the pipeline */ | ||
| pipe = pipeline_new(NULL, pipe_desc->primary.r.instance_id, | ||
| pipe = pipeline_new(heap, pipe_desc->primary.r.instance_id, |
There was a problem hiding this comment.
right, maybe put a comment there for now to make re-discovery easier
7317b18 to
c029d49
Compare
|
V4 snapshot pushed:
|
|
Example output with V4 patchset: |
c029d49 to
9c778e4
Compare
|
V5 pushed:
|
9c778e4 to
c4b127f
Compare
|
V6 pushed:
|
c4b127f to
ad359d6
Compare
|
V7 submitted:
|
ad359d6 to
c7e9a37
Compare
|
V8 submitted:
|
c7e9a37 to
8af1be4
Compare
|
V9 submitted:
|
|
V10:
|
aa5efe0 to
35a61b6
Compare
|
V11 pushed:
|
35a61b6 to
214c051
Compare
|
V12 pushed:
|
- add arch_schedulers_get_for_core() for task-carried core routing - route 8 task-aware scheduler callers via task->core under CONFIG_SOF_USERSPACE_LL - fix zephyr_domain_thread_tid() to accept core parameter instead of hardcoding core 0 - create domain threads for secondary cores in secondary_core_init() - remove FIXME workaround from arch_schedulers_get() Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
No need to copy the trace context object to buffer object, when audio pipelines are running in user-space. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
To make ipc4_create_buffer() usable from user-space, do not call cpu_get_id() but instead rely on "src->ipc_config.core". If code is run in kernel space, check the core matching current active core, but skip the check if run in user-space (as check is privileged). Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Make ipc_comp_connect() safe to run in user-space with limited functionality. The core id queries are privileged, so limit connections to cases where pipeline is running on 0. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Move handling of SOF_IPC4_MOD_CONFIG_GET/GET to user-space IPC thread when SOF is built with CONFIG_SOF_USERSPACE_LL. Handling these IPC messages require calls to module interface get/set_attribute() methods, which must be run in user-space. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Move handling of SOF_IPC4_MOD_BIND/UNBIND to user-space IPC thread when SOF is built with CONFIG_SOF_USERSPACE_LL. Handling these IPC messages require calls to module interface bind/unbind() methods, which must be run in user-space. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Move handling of SOF_IPC4_IPC4_MOD_INIT_INSTANCE partially to user-space IPC thread when SOF is built with CONFIG_SOF_USERSPACE_LL. Module init involves multiple privileged actions, so part of module init handling is still done in kernel space, but the module specific initialization is run in user-space. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Move handling of SOF_IPC4_GLB_SET_PIPELINE_STATE to user-space IPC thread when SOF is built with CONFIG_SOF_USERSPACE_LL. The IPC compound message helpers in IPC common.h are turned into system calls, allowing the user-space IPC thread to synchronize with kernel IPC thread that still does the low-level IPC messaging. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Move handling of SOF_IPC4_MOD_LARGE_CONFIG_GET/SET to user-space IPC thread when SOF is built with CONFIG_SOF_USERSPACE_LL. Handling of these IPCs requires calling to module specific code via the module get/set_large_config() method, so this code needs to run in user-space context if audio pipelines are running in user-space. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
The LL user-space heap was sized using CONFIG_SOF_ZEPHYR_USERSPACE_MODULE_HEAP_SIZE (16 KB), which is the per-module heap size. This heap is shared across ALL simultaneously active pipelines for module allocations, buffer allocations, IPC structures, and host DMA data. With 8 concurrent pipelines the 16 KB budget was exhausted, causing ENOMEM failures in the multiple-pipeline test. Add CONFIG_SOF_ZEPHYR_LL_USER_HEAP_SIZE (default 128 KB) so the LL scheduler heap can be sized independently. Parameterize sys_user_heap_init() to accept the heap size from its caller. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Set CONFIG_SOF_ZEPHYR_LL_USER_HEAP_SIZE to 128kB in the LL user-space overlay. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Make ipc_msg_send() a Zephyr system call so audio processing modules running in user-space LL threads can queue IPC messages (e.g. position updates, notifications) back to the host. The change takes effect only if CONFIG_SOF_USERSPACE_LL=y. Follows the same pattern used for ipc_msg_reply(): a dedicated header with __syscall declaration, z_impl/z_vrfy split, and syscall header registration in CMakeLists.txt. The verifier validates that the msg struct is writable (the implementation touches the list linkage) and that the data buffer, when provided, is readable up to msg->tx_size bytes. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com> (cherry picked from commit b25c15c)
Add an optional heap parameter to ipc_msg_w_ext_init() and ipc_msg_init() so callers can direct allocations to a specific heap. When the heap argument is NULL the existing rzalloc() path is used; when non-NULL, sof_heap_alloc()/sof_heap_free() are used instead. This allows IPC messages to be allocated from userspace-accessible heaps. For audio module contexts, introduce mod_ipc_msg_w_ext_init() and mod_ipc_msg_init() in generic.h. These use mod_zalloc()/ mod_free() for allocations that are automatically tracked and freed with the module lifecycle. ipc_msg_w_ext_init() is moved from a static inline in msg.h to a non-inline function in ipc-common.c due to the additional sof_heap_alloc dependency. Update all existing callers: - Module context callers (cadence, tdfb, sound_dose) use the new mod_ipc_msg_*() variants. - host-zephyr.c uses hd->heap, pipeline-graph.c uses the heap parameter from pipeline_new(). - Remaining kernel-context callers pass NULL for the default heap. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com> (cherry picked from commit 11a17d5)
Add a new test to userspace_ll set that tests more of the functionality needed to run full audio pipelines in user-space. The test creates a pipeline with two components (IPC4 host and DAI copiers), does pipeline prepare, one copy cycle in prepared state and tears down the pipeline. One user-space thread is created to manage the pipelines. This would be equivalent to user IPC handler thread. Another user-space thread is created for the LL scheduler. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Place the pipeline position lookup table in the sysuser memory partition and replace k_spinlock with a dynamically allocated k_mutex when CONFIG_SOF_USERSPACE_LL is enabled. Spinlocks disable interrupts which is a privileged operation unavailable from user-mode threads. The mutex pointer is stored in a separate APP_SYSUSER_BSS variable outside the SHARED_DATA struct so Zephyr's kernel object tracking can recognize it for syscall verification. Move pipeline_posn_init() from task_main_start() to primary_core_init() before platform_init(), so the mutex is allocated before ipc_user_init() grants thread access to it. In pipeline_posn_get(), bypass the sof_get() kernel singleton and access the shared structure directly when running in user-space. Grant the ipc_user_init thread access to the pipeline position mutex via new pipeline_posn_grant_access() helper. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
If SOF is built with CONFIG_SOF_USERSPACE_LL, the IPC user handled will require access to coldrodata sections to initialize audio modules. This logic is not required for LLEXT modules, which have existing code to add access to coldrodata (and other sections). This commit is needed for builds where LLEXT is not used. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
This is a set of temporary changes to audio code to remove calls to privileged interfaces that are not mandatory to run simple audio tests. These need proper solutions to be able to run all use-cases in user LL version. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Pull in Zephyr PR. Link: zephyrproject-rtos/zephyr#107341 Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
25e27c9 to
a22a976
Compare
|
V17 pushed:
|
SOF has recently gained ability to run DP (=preemptable audio tasks) in Zephyr user-space.
This PR is an early stage pull-request for changes to extend this capability to all of the audio pipeline code, and specifically the LL (low-latency) tasks.
This early stage as the design is not set in stone and the PR uses a number of short cuts in order to move (and tests) incrementally larger sets of audio functionality.