Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/ipc/ipc-helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand Down
13 changes: 8 additions & 5 deletions src/lib/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Author: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>

#include <rtos/atomic.h>
#include <rtos/kernel.h>
#include <sof/audio/audio_stream.h>
#include <sof/audio/buffer.h>
#include <sof/audio/component.h>
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not 100% sure about this. I've been trying to make the heap decision a built-time choise (if LL_USER enabled in build, use sof_sys_user_heap_get()) to make it easy to understand in which circumstances the code path is taken.

This adds the calling thread as a variable to decide how resources are allocated. But I get in this case we could have mixed use of DMA channels both from kernel and user threads, so the simple logic is not sufficient. And the heap used is stored in "dma->heap", so this stays correct. Hmm, this is a different pattern, but leaning towards +1 for this.

@lyakh lyakh Jun 22, 2026

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.

@kv2019i I tried to minimise changes - for non-userspace cases at least. I've just checked, using sof_sys_user_heap_get() unconditionally works too. What's your preference - keep this or make it depend on IS_ENABLED(CONFIG_...)?

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++) {
Expand Down
26 changes: 17 additions & 9 deletions src/schedule/zephyr_domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Comment thread
lyakh marked this conversation as resolved.

/* 10 is rather random, we better not accumulate 10 missed timer interrupts */
k_sem_init(dt->sem, 0, 10);

Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
12 changes: 9 additions & 3 deletions src/schedule/zephyr_ll.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -616,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);

Expand Down
2 changes: 2 additions & 0 deletions zephyr/include/sof/lib/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading