From c501a10cb20c2a88630ac2453e4198e0f0fbea62 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 10 Jun 2026 12:58:00 +0200 Subject: [PATCH 1/5] ipc: disable memory zones for IPC4 Memory zones are only used with IPC3, mark them as such. Signed-off-by: Guennadi Liakhovetski --- src/ipc/ipc-helper.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ipc/ipc-helper.c b/src/ipc/ipc-helper.c index b7ef418e0339..737c3b73370c 100644 --- a/src/ipc/ipc-helper.c +++ b/src/ipc/ipc-helper.c @@ -67,6 +67,7 @@ __cold struct comp_buffer *buffer_new(struct mod_alloc_ctx *alloc, return NULL; } +#if CONFIG_IPC_MAJOR_3 /* memory zones and caps are deprecated - convert to flags */ if (desc->caps & SOF_MEM_CAPS_DMA) flags |= SOF_MEM_FLAG_DMA; @@ -77,6 +78,7 @@ __cold struct comp_buffer *buffer_new(struct mod_alloc_ctx *alloc, if (desc->caps) tr_warn(&buffer_tr, "Deprecated buffer caps 0x%x used, convert to flags 0x%x", desc->caps, flags); +#endif /* allocate buffer */ buffer = buffer_alloc(alloc, desc->size, flags, PLATFORM_DCACHE_ALIGN, From ae8ab42e365e29294513204ad571b20df5925663 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 10 Jun 2026 15:17:01 +0200 Subject: [PATCH 2/5] dma: allocate on userspace heap when running in userspace When initialising in userspace use the userspace heap for channel memory allocations. Signed-off-by: Guennadi Liakhovetski --- src/lib/dma.c | 13 ++++++++----- zephyr/include/sof/lib/dma.h | 2 ++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/lib/dma.c b/src/lib/dma.c index 70ac5c975058..81d02626a05d 100644 --- a/src/lib/dma.c +++ b/src/lib/dma.c @@ -5,6 +5,7 @@ // Author: Ranjani Sridharan #include +#include #include #include #include @@ -134,7 +135,7 @@ void z_impl_sof_dma_put(struct sof_dma *dma) key = k_spin_lock(&dma->lock); if (--dma->sref == 0) { - rfree(dma->chan); + sof_heap_free(dma->heap, dma->chan); dma->chan = NULL; } @@ -146,18 +147,20 @@ void z_impl_sof_dma_put(struct sof_dma *dma) static int dma_init(struct sof_dma *dma) { struct dma_chan_data *chan; + struct k_heap *heap = thread_is_userspace(k_current_get()) ? sof_sys_user_heap_get() : NULL; int i; /* allocate dma channels */ - dma->chan = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, - sizeof(struct dma_chan_data) * dma->plat_data.channels); - + dma->chan = sof_heap_alloc(heap, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, + sizeof(struct dma_chan_data) * dma->plat_data.channels, 0); if (!dma->chan) { - tr_err(&dma_tr, "dma_probe_sof(): dma %d allocaction of channels failed", + tr_err(&dma_tr, "dma %d allocation of channels failed", dma->plat_data.id); return -ENOMEM; } + dma->heap = heap; + memset(dma->chan, 0, sizeof(struct dma_chan_data) * dma->plat_data.channels); /* init work */ for (i = 0, chan = dma->chan; i < dma->plat_data.channels; i++, chan++) { diff --git a/zephyr/include/sof/lib/dma.h b/zephyr/include/sof/lib/dma.h index 509495634097..e11899d07a4c 100644 --- a/zephyr/include/sof/lib/dma.h +++ b/zephyr/include/sof/lib/dma.h @@ -200,7 +200,9 @@ struct dma_plat_data { }; #ifdef CONFIG_ZEPHYR_NATIVE_DRIVERS +struct k_heap; struct sof_dma { + struct k_heap *heap; #else struct dma { #endif From bd5a53824e190139b5799840cceeb1c1a8dc8139 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 10 Jun 2026 15:24:02 +0200 Subject: [PATCH 3/5] schedule: ll: allocate semaphores only for used cores Instead of allocating semaphores during global initialisation, do that later when initialising the domain for specific cores. This also automatically grants access rights to the allocating thread. Signed-off-by: Guennadi Liakhovetski --- src/schedule/zephyr_domain.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/schedule/zephyr_domain.c b/src/schedule/zephyr_domain.c index ef649f975be8..3837f0b135c6 100644 --- a/src/schedule/zephyr_domain.c +++ b/src/schedule/zephyr_domain.c @@ -319,6 +319,12 @@ static int zephyr_domain_thread_init(struct ll_schedule_domain *domain, dt->handler = NULL; dt->arg = NULL; + dt->sem = k_object_alloc(K_OBJ_SEM); + if (!dt->sem) { + tr_err(&ll_tr, "Failed to allocate semaphore for core %d", core); + return -ENOMEM; + } + /* 10 is rather random, we better not accumulate 10 missed timer interrupts */ k_sem_init(dt->sem, 0, 10); @@ -328,6 +334,8 @@ static int zephyr_domain_thread_init(struct ll_schedule_domain *domain, dt->ll_thread = k_object_alloc(K_OBJ_THREAD); if (!dt->ll_thread) { tr_err(&ll_tr, "Failed to allocate thread object for core %d", core); + k_object_free(dt->sem); + dt->sem = NULL; return -ENOMEM; } @@ -473,6 +481,11 @@ static void zephyr_domain_thread_free(struct ll_schedule_domain *domain, dt->ll_thread = NULL; } + if (dt->sem) { + k_object_free(dt->sem); + dt->sem = NULL; + } + tr_info(&ll_tr, "thread_free done, core %d", core); } @@ -530,11 +543,11 @@ APP_TASK_DATA static const struct ll_schedule_domain_ops zephyr_domain_ops = { #endif }; +/* Core 0 only */ struct ll_schedule_domain *zephyr_domain_init(int clk) { struct ll_schedule_domain *domain; struct zephyr_domain *zephyr_domain; - struct zephyr_domain_thread *dt; int core; domain = domain_init(SOF_SCHEDULE_LL_TIMER, clk, false, @@ -584,14 +597,9 @@ struct ll_schedule_domain *zephyr_domain_init(int clk) ll_sch_domain_set_pdata(domain, zephyr_domain); for (core = 0; core < CONFIG_CORE_COUNT; core++) { - dt = zephyr_domain->domain_thread + core; -#ifdef CONFIG_SOF_USERSPACE_LL - dt->sem = k_object_alloc(K_OBJ_SEM); - if (!dt->sem) { - tr_err(&ll_tr, "Failed to allocate semaphore for core %d", core); - k_panic(); - } -#else +#ifndef CONFIG_SOF_USERSPACE_LL + struct zephyr_domain_thread *dt = zephyr_domain->domain_thread + core; + /* not allocated dynamically when LL in kernel space */ dt->sem = &dt->sem_obj; #endif From 0caa189d0c9215e122cb38c05140a9cc9bbadbbc Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 10 Jun 2026 15:29:59 +0200 Subject: [PATCH 4/5] schedule: ll: initialise task object to 0 This is needed at least to set the .priv_data pointer to NULL. Signed-off-by: Guennadi Liakhovetski --- src/schedule/zephyr_ll.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/schedule/zephyr_ll.c b/src/schedule/zephyr_ll.c index 36bacda0c9ad..2c27daadc910 100644 --- a/src/schedule/zephyr_ll.c +++ b/src/schedule/zephyr_ll.c @@ -552,8 +552,14 @@ static const struct scheduler_ops zephyr_ll_ops = { #if CONFIG_SOF_USERSPACE_LL struct task *zephyr_ll_task_alloc(void) { - return sof_heap_alloc(zephyr_ll_user_heap(), SOF_MEM_FLAG_USER, - sizeof(struct task), sizeof(void *)); + struct task *task = sof_heap_alloc(zephyr_ll_user_heap(), SOF_MEM_FLAG_USER, + sizeof(*task), sizeof(void *)); + + if (task) + /* At least .priv_data must be NULL for zephyr_ll_task_init() */ + memset(task, 0, sizeof(*task)); + + return task; } #endif /* CONFIG_SOF_USERSPACE_LL */ From 1d4e7d7314854ddf9f76afb76a3705294e5d18fb Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 10 Jun 2026 15:34:30 +0200 Subject: [PATCH 5/5] schedule: ll: allocate coherent memory in userspace mode too Also when userspace is used scheduler instances have to be allocated uncached. Signed-off-by: Guennadi Liakhovetski --- src/schedule/zephyr_ll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schedule/zephyr_ll.c b/src/schedule/zephyr_ll.c index 2c27daadc910..ddae93eee8b7 100644 --- a/src/schedule/zephyr_ll.c +++ b/src/schedule/zephyr_ll.c @@ -622,7 +622,7 @@ __cold int zephyr_ll_scheduler_init(struct ll_schedule_domain *domain) #if CONFIG_SOF_USERSPACE_LL heap = zephyr_ll_user_heap(); - flags = SOF_MEM_FLAG_USER; + flags = SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT; #endif tr_dbg(&ll_tr, "init on core %d", core);