Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3dda59a
vregion: remove need to include rtos/alloc.h in !CONFIG_SOF_VREGIONS …
Jun 3, 2026
4f71ecd
zephyr: lib: Remove ctx_alloc.h and put the contents into rtos/alloc.h
Jun 1, 2026
ab33679
posix: alloc.h: Add dummy mod_alloc_ctx and sof_ctx_alloc() support
Jun 3, 2026
c00d82c
ipc4: Replace interim_heap_bytes and lifetime_heap_bytes with heap_bytes
Jun 3, 2026
61ef7a4
debug_stream: make ds_send_text_record() a syscall
Apr 29, 2026
6883900
debug_stream: Export ds_msg() to allow using it in loadable modules
May 28, 2026
1acc1d9
module-adapter: Move pipeline_comp_dp_task_init() after mod struct inits
Mar 5, 2026
b3ea8e3
module-adapter: Size DP heap from IPC ext init data
Mar 5, 2026
f627dfa
pipeline: Use dp_data stack size for DP task
Mar 5, 2026
4eff999
schedule: dp: Set thread name with component ID
May 7, 2026
76c65e6
audio: src: move filter and delay line allocation to init phase
May 11, 2026
c420b50
lib: vregion: lazy interim heap creation from remaining lifetime space
May 12, 2026
1252ff9
lib: vregion: fix interim heap init alignment and small size assert
Jun 2, 2026
1c2831d
vregion: call vregion_set_interim() from pipeline_comp_complete()
May 26, 2026
d650f07
module_adapter: fix memory API debug check for DP modules
May 26, 2026
8443be4
pipeline: allocate shared vregion for LL modules
May 26, 2026
a2d5d59
pipeline: add alloc context object to pipeline
May 28, 2026
fe7fbe1
topology2: Increase widget default value for stack from 4k to 8k
May 7, 2026
eefe685
topology2: cavs-nocodec.conf: Fine tune SRC DP memory requirements
May 7, 2026
b59e0c9
topology2: Remove lifetime and shared -bytes_requirement widget attri…
Jun 2, 2026
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
50 changes: 50 additions & 0 deletions posix/include/rtos/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,56 @@ void sof_heap_free(struct k_heap *heap, void *addr);
struct k_heap *sof_sys_heap_get(void);
struct k_heap *sof_sys_user_heap_get(void);

/* Posix version of struct mod_alloc_ctx without vregion support */
struct vregion;

struct mod_alloc_ctx {
struct k_heap *heap;
struct vregion *vreg;
};

/**
* Allocate memory from a mod_alloc_ctx context.
* Dummy version, only heap allocation is supported
*/
static inline void *sof_ctx_alloc(struct mod_alloc_ctx *ctx, uint32_t flags,
size_t size, size_t alignment)
{
return sof_heap_alloc(ctx ? ctx->heap : NULL, flags, size, alignment);
}

/**
* Allocate zero-initialized memory from a mod_alloc_ctx context.
* @param ctx Allocation context.
* @param flags Allocation flags (SOF_MEM_FLAG_*).
* @param size Size in bytes.
* @param alignment Required alignment in bytes.
* @return Pointer to allocated memory or NULL on failure.
*/
static inline void *sof_ctx_zalloc(struct mod_alloc_ctx *ctx, uint32_t flags,
size_t size, size_t alignment)
{
void *ptr = sof_ctx_alloc(ctx, flags, size, alignment);

if (ptr)
memset(ptr, 0, size);

return ptr;
}

/**
* Free memory allocated from a mod_alloc_ctx context.
* @param ctx Allocation context.
* @param ptr Pointer to free.
*/
static inline void sof_ctx_free(struct mod_alloc_ctx *ctx, void *ptr)
{
if (!ptr)
return;

sof_heap_free(ctx ? ctx->heap : NULL, ptr);
}

/**
* Calculates length of the null-terminated string.
* @param s String.
Expand Down
1 change: 0 additions & 1 deletion src/audio/buffers/comp_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include <rtos/alloc.h>
#include <rtos/cache.h>
#include <sof/lib/vregion.h>
#include <sof/ctx_alloc.h>
#include <sof/list.h>
#include <sof/schedule/dp_schedule.h>
#include <rtos/spinlock.h>
Expand Down
1 change: 0 additions & 1 deletion src/audio/buffers/ring_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include <sof/trace/trace.h>
#include <sof/lib/uuid.h>
#include <sof/lib/vregion.h>
#include <sof/ctx_alloc.h>

#include <sof/audio/module_adapter/module/generic.h>
#include <sof/audio/ring_buffer.h>
Expand Down
6 changes: 3 additions & 3 deletions src/audio/module_adapter/module/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include <sof/audio/data_blob.h>
#include <sof/lib/fast-get.h>
#include <sof/lib/vregion.h>
#include <sof/ctx_alloc.h>
#include <sof/schedule/dp_schedule.h>
#if CONFIG_IPC_MAJOR_4
#include <ipc4/header.h>
Expand All @@ -29,8 +28,9 @@
/* The __ZEPHYR__ condition is to keep cmocka tests working */
#if CONFIG_MODULE_MEMORY_API_DEBUG && defined(__ZEPHYR__)
#define MEM_API_CHECK_THREAD(res) do { \
if ((res)->rsrc_mngr != k_current_get()) \
LOG_WRN("mngr %p != cur %p", (res)->rsrc_mngr, k_current_get()); \
k_tid_t tid = k_current_get(); \
if ((res)->rsrc_mngr != tid && (res)->dp_thread != tid) \
LOG_WRN("cur %p != mngr %p or dp %p", tid, (res)->rsrc_mngr, (res)->dp_thread); \
} while (0)
#else
#define MEM_API_CHECK_THREAD(res)
Expand Down
167 changes: 114 additions & 53 deletions src/audio/module_adapter/module_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,37 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv,
#endif

static struct vregion *module_adapter_dp_heap_new(const struct comp_ipc_config *config,
const struct module_ext_init_data *ext_init,
size_t *heap_size)
{
/* src-lite with 8 channels has been seen allocating 14k in one go */
/* FIXME: the size will be derived from configuration */
const size_t buf_size = 28 * 1024;
size_t buf_size = CONFIG_SOF_USERSPACE_DP_DEFAULT_HEAP_SIZE;

/*
* A 1-to-1 replacement of the original heap implementation would be to
* have "lifetime size" equal to 0. But (1) this is invalid for
* vregion_create() and (2) we gradually move objects, that are simple
* to move to the lifetime buffer. Make it 4k for the beginning.
*/
return vregion_create(4096, buf_size - 4096);
#if CONFIG_IPC_MAJOR_4
if (config->ipc_extended_init && ext_init && ext_init->dp_data &&
ext_init->dp_data->heap_bytes > 0) {
if (ext_init->dp_data->heap_bytes > 64*1024*1024) {
LOG_ERR("Bad heap size %u bytes for %#x",
ext_init->dp_data->heap_bytes, config->id);
return NULL;
}

buf_size = ext_init->dp_data->heap_bytes;

LOG_INF("%zu byte heap size requested in IPC for %#x", buf_size, config->id);
}
#endif

*heap_size = buf_size;

return vregion_create(buf_size);
}

static struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv,
const struct comp_ipc_config *config)
static
struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv,
const struct comp_ipc_config *config,
const struct module_ext_init_data *ext_init,
struct mod_alloc_ctx *ppl_alloc)
{
struct k_heap *mod_heap;
struct vregion *mod_vreg;
Expand All @@ -91,41 +105,58 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
uint32_t flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ?
SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER;
size_t heap_size;
bool use_ppl_alloc = ppl_alloc &&
config->proc_domain == COMP_PROCESSING_DOMAIN_LL;

if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP && IS_ENABLED(CONFIG_USERSPACE) &&
!IS_ENABLED(CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP)) {
mod_vreg = module_adapter_dp_heap_new(config, &heap_size);
mod_vreg = module_adapter_dp_heap_new(config, ext_init, &heap_size);
if (!mod_vreg) {
comp_cl_err(drv, "Failed to allocate DP module heap / vregion");
return NULL;
}
mod_heap = NULL;
} else if (use_ppl_alloc) {
mod_vreg = ppl_alloc->vreg ? vregion_get(ppl_alloc->vreg) : NULL;
mod_heap = ppl_alloc->heap;
heap_size = 0;
} else {
mod_heap = drv->user_heap;
heap_size = 0;
mod_vreg = NULL;
}

if (!mod_vreg)
if (use_ppl_alloc) {
/* LL modules use the pipeline's alloc context */
mod = sof_ctx_alloc(ppl_alloc, flags, sizeof(*mod), 0);
} else if (!mod_vreg) {
Comment thread
jsarha marked this conversation as resolved.
mod = sof_heap_alloc(mod_heap, flags, sizeof(*mod), 0);
else if (flags & SOF_MEM_FLAG_COHERENT)
mod = vregion_alloc_coherent(mod_vreg, VREGION_MEM_TYPE_LIFETIME, sizeof(*mod));
else
mod = vregion_alloc(mod_vreg, VREGION_MEM_TYPE_LIFETIME, sizeof(*mod));
} else if (flags & SOF_MEM_FLAG_COHERENT) {
mod = vregion_alloc_coherent(mod_vreg, sizeof(*mod));
} else {
mod = vregion_alloc(mod_vreg, sizeof(*mod));
}

if (!mod) {
comp_cl_err(drv, "failed to allocate memory for module");
goto emod;
}

struct mod_alloc_ctx *alloc = rmalloc(flags, sizeof(*alloc));
struct mod_alloc_ctx *alloc;

if (!alloc)
goto ealloc;
if (use_ppl_alloc) {
/* LL modules share the pipeline's alloc context */
alloc = ppl_alloc;
} else {
alloc = rzalloc(flags, sizeof(*alloc));
if (!alloc)
goto ealloc;

alloc->heap = mod_heap;
alloc->vreg = mod_vreg;
}

memset(mod, 0, sizeof(*mod));
alloc->heap = mod_heap;
alloc->vreg = mod_vreg;
mod->priv.resources.alloc = alloc;
mod_resource_init(mod);

Expand All @@ -135,8 +166,10 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
* then it can be cached. Effectively it can be only cached in
* single-core configurations.
*/
if (mod_vreg)
dev = vregion_alloc_coherent(mod_vreg, VREGION_MEM_TYPE_LIFETIME, sizeof(*dev));
if (use_ppl_alloc)
dev = sof_ctx_alloc(ppl_alloc, SOF_MEM_FLAG_COHERENT, sizeof(*dev), 0);
else if (mod_vreg)
dev = vregion_alloc_coherent(mod_vreg, sizeof(*dev));
else
dev = sof_heap_alloc(mod_heap, SOF_MEM_FLAG_COHERENT, sizeof(*dev), 0);

Expand All @@ -154,40 +187,47 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
return mod;

edev:
rfree(alloc);
if (!use_ppl_alloc)
rfree(alloc);
ealloc:
if (mod_vreg)
if (use_ppl_alloc)
sof_ctx_free(ppl_alloc, mod);
else if (mod_vreg)
vregion_free(mod_vreg, mod);
else
sof_heap_free(mod_heap, mod);
emod:
vregion_put(mod_vreg);
if (use_ppl_alloc)
vregion_put(ppl_alloc->vreg);
else
vregion_put(mod_vreg);

return NULL;
}

static void module_adapter_mem_free(struct processing_module *mod)
{
struct mod_alloc_ctx *alloc = mod->priv.resources.alloc;
struct k_heap *mod_heap = alloc->heap;
bool ppl_alloc = mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL &&
mod->dev->pipeline && mod->dev->pipeline->alloc == alloc;

/*
* In principle it shouldn't even be needed to free individual objects
* on the module heap since we're freeing the heap itself too
*/
#if CONFIG_IPC_MAJOR_4
sof_heap_free(mod_heap, mod->priv.cfg.input_pins);
sof_heap_free(alloc->heap, mod->priv.cfg.input_pins);
#endif
if (alloc->vreg) {
struct vregion *mod_vreg = alloc->vreg;

vregion_free(mod_vreg, mod->dev);
vregion_free(mod_vreg, mod);
if (!vregion_put(mod_vreg))
sof_ctx_free(alloc, mod->dev);
sof_ctx_free(alloc, mod);

if (ppl_alloc) {
/* alloc belongs to pipeline, just release vregion reference */
vregion_put(alloc->vreg);
} else if (alloc->vreg) {
if (!vregion_put(alloc->vreg))
rfree(alloc);
} else {
sof_heap_free(mod_heap, mod->dev);
sof_heap_free(mod_heap, mod);
rfree(alloc);
}
}
Expand Down Expand Up @@ -231,8 +271,32 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
return NULL;
}
#endif
const struct module_ext_init_data *ext_init =
#if CONFIG_IPC_MAJOR_4
&ext_data;
#else
NULL;
#endif

struct processing_module *mod = module_adapter_mem_alloc(drv, config);
#if CONFIG_IPC_MAJOR_4
struct ipc_comp_dev *ipc_pipe;
struct ipc *ipc = ipc_get();
struct mod_alloc_ctx *ppl_alloc = NULL;

/* resolve the pipeline pointer early to pass its alloc to mem_alloc */
ipc_pipe = ipc_get_comp_by_ppl_id(ipc, COMP_TYPE_PIPELINE, config->pipeline_id,
IPC_COMP_IGNORE_REMOTE);
if (ipc_pipe && ipc_pipe->pipeline)
ppl_alloc = ipc_pipe->pipeline->alloc;
#endif

struct processing_module *mod = module_adapter_mem_alloc(drv, config, ext_init,
#if CONFIG_IPC_MAJOR_4
ppl_alloc
#else
NULL
#endif
);

if (!mod)
return NULL;
Expand All @@ -245,6 +309,18 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,

struct comp_dev *dev = mod->dev;

dst = &mod->priv.cfg;
/*
* NOTE: dst->ext_data points to stack variable and contains
* pointers to IPC payload mailbox, so its only valid in
* functions that are called from this function. This is
* why the pointer is set to NULL before this function
* exits.
*/
#if CONFIG_IPC_MAJOR_4
dst->ext_data = &ext_data;
#endif

#if CONFIG_ZEPHYR_DP_SCHEDULER
/* create a task for DP processing */
if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP) {
Expand All @@ -257,16 +333,6 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
}
#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */

dst = &mod->priv.cfg;
/*
* NOTE: dst->ext_data points to stack variable and contains
* pointers to IPC payload mailbox, so its only valid in
* functions that called from this function. This why
* the pointer is set NULL before this function exits.
*/
#if CONFIG_IPC_MAJOR_4
dst->ext_data = &ext_data;
#endif
ret = module_adapter_init_data(dev, dst, config, &spec);
if (ret) {
comp_err(dev, "%d: module init data failed",
Expand All @@ -289,12 +355,7 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
goto err;

#if CONFIG_IPC_MAJOR_4
struct ipc_comp_dev *ipc_pipe;
struct ipc *ipc = ipc_get();

/* set the pipeline pointer if ipc_pipe is valid */
ipc_pipe = ipc_get_comp_by_ppl_id(ipc, COMP_TYPE_PIPELINE, config->pipeline_id,
IPC_COMP_IGNORE_REMOTE);
if (ipc_pipe) {
dev->pipeline = ipc_pipe->pipeline;

Expand Down
5 changes: 2 additions & 3 deletions src/audio/module_adapter/module_adapter_ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,9 @@ int module_ext_init_decode(const struct comp_driver *drv, struct module_ext_init
}
ext_data->dp_data = dp_data;
comp_cl_info(drv,
"init_ext_obj_dp_data domain %u stack %u interim %u lifetime %u shared %u",
"init_ext_obj_dp_data domain %u stack %u heap %u",
dp_data->domain_id, dp_data->stack_bytes,
dp_data->interim_heap_bytes, dp_data->lifetime_heap_bytes,
dp_data->shared_bytes);
dp_data->heap_bytes);
break;
}
case IPC4_MOD_INIT_DATA_ID_MODULE_DATA:
Expand Down
Loading
Loading