Skip to content
Merged
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
8 changes: 3 additions & 5 deletions src/audio/codec/dts/dts.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ static void *dts_effect_allocate_codec_memory(void *mod_void, unsigned int lengt

Copy link
Collaborator

Choose a reason for hiding this comment

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

commit doesn't say why these are renamed. Just to make them shorter?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, simply to make the names shorter and not to trigger line wrapping storm all around the place when all modules are changed to use module API for memory allocations.

comp_dbg(dev, "dts_effect_allocate_codec_memory() start");

pMem = module_allocate_memory(mod, (uint32_t)length, (uint32_t)alignment);
pMem = mod_alloc_align(mod, (uint32_t)length, (uint32_t)alignment);

if (pMem == NULL)
comp_err(dev,
Expand All @@ -42,10 +42,10 @@ static void dts_effect_free_codec_memory(void *mod_void, void *pMem)

comp_dbg(dev, "dts_effect_free_codec_memory() start");

int ret = module_free_memory(mod, pMem);
int ret = mod_free(mod, pMem);

if (ret)
comp_err(dev, "dts_effect_free_codec_memory() module_free_memory failed %d", ret);
comp_err(dev, "dts_effect_free_codec_memory() mod_free failed %d", ret);

comp_dbg(dev, "dts_effect_free_codec_memory() done");
}
Expand Down Expand Up @@ -405,8 +405,6 @@ static int dts_codec_free(struct processing_module *mod)
if (ret)
comp_err(dev, "dts_codec_free() failed %d %d", ret, dts_result);

module_free_all_memory(mod);

comp_dbg(dev, "dts_codec_free() done");

return ret;
Expand Down
18 changes: 9 additions & 9 deletions src/audio/module_adapter/module/cadence.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ static int init_memory_tables(struct processing_module *mod)
goto err;
}
/* Allocate memory for this type, taking alignment into account */
ptr = module_allocate_memory(mod, mem_size, mem_alignment);
ptr = mod_alloc_align(mod, mem_size, mem_alignment);
if (!ptr) {
comp_err(dev, "init_memory_tables() error %x: failed to allocate memory for %d",
ret, mem_type);
Expand Down Expand Up @@ -563,13 +563,13 @@ static int init_memory_tables(struct processing_module *mod)
return 0;
err:
if (scratch)
module_free_memory(mod, scratch);
mod_free(mod, scratch);
if (persistent)
module_free_memory(mod, persistent);
mod_free(mod, persistent);
if (codec->mpd.in_buff)
module_free_memory(mod, codec->mpd.in_buff);
mod_free(mod, codec->mpd.in_buff);
if (codec->mpd.out_buff)
module_free_memory(mod, codec->mpd.out_buff);
mod_free(mod, codec->mpd.out_buff);
return ret;
}

Expand Down Expand Up @@ -688,7 +688,7 @@ static int cadence_codec_prepare(struct processing_module *mod,
return ret;
}

cd->mem_tabs = module_allocate_memory(mod, mem_tabs_size, 4);
cd->mem_tabs = mod_alloc(mod, mem_tabs_size);
if (!cd->mem_tabs) {
comp_err(dev, "cadence_codec_prepare() error: failed to allocate space for memtabs");
return -ENOMEM;
Expand Down Expand Up @@ -732,7 +732,7 @@ static int cadence_codec_prepare(struct processing_module *mod,
comp_dbg(dev, "cadence_codec_prepare() done");
return 0;
free:
module_free_memory(mod, cd->mem_tabs);
mod_free(mod, cd->mem_tabs);
return ret;
}

Expand Down Expand Up @@ -847,7 +847,7 @@ static int cadence_codec_reset(struct processing_module *mod)
* So, free all memory associated with runtime params. These will be reallocated during
* prepare.
*/
module_free_all_memory(mod);
mod_free_all(mod);

/* reset to default params */
API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, NULL, ret);
Expand All @@ -867,7 +867,7 @@ static int cadence_codec_free(struct processing_module *mod)
struct cadence_codec_data *cd = module_get_private_data(mod);

rfree(cd->setup_cfg.data);
module_free_all_memory(mod);
mod_free_all(mod);
rfree(cd->self);
rfree(cd);
return 0;
Expand Down
73 changes: 66 additions & 7 deletions src/audio/module_adapter/module/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,31 @@ int module_init(struct processing_module *mod)
return 0;
}

void *module_allocate_memory(struct processing_module *mod, uint32_t size, uint32_t alignment)
/**
* Allocates aligned memory block for module.
* @param mod Pointer to the module this memory block is allocatd for.
* @param bytes Size in bytes.
* @param alignment Alignment in bytes.
* @return Pointer to the allocated memory or NULL if failed.
*
* The allocated memory is automatically freed when the module is unloaded.
*/
void *mod_alloc_align(struct processing_module *mod, uint32_t size, uint32_t alignment)
{
struct comp_dev *dev = mod->dev;
struct module_memory *container;
void *ptr;

if (!size) {
comp_err(dev, "module_allocate_memory: requested allocation of 0 bytes.");
comp_err(dev, "mod_alloc: requested allocation of 0 bytes.");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we really need to include the function name in the error message? Zephyr automatically prefixes log entries with the function name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, but I do not want to mess with this commit that is strictly replace-string operation on the source tree. Maybe I should go through all our modules in another commit, in the next PR.

Copy link
Member

Choose a reason for hiding this comment

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

actually, now that we are Zephyr only, we should use LOG(), but this can be another PR.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@lgirdwood didn't we already conclude that no, we want to keep audio specific macros for audio codes that add audio topology information (component and pipe ids) to the log messages. For generic code outside modules, using plain Zephyr LOG is then ok (when not in module context).

return NULL;
}

/* Allocate memory container */
container = rzalloc(SOF_MEM_FLAG_USER,
sizeof(struct module_memory));
if (!container) {
comp_err(dev, "module_allocate_memory: failed to allocate memory container.");
comp_err(dev, "mod_alloc: failed to allocate memory container.");
return NULL;
}

Expand All @@ -136,18 +145,60 @@ void *module_allocate_memory(struct processing_module *mod, uint32_t size, uint3
ptr = rballoc(SOF_MEM_FLAG_USER, size);

if (!ptr) {
comp_err(dev, "module_allocate_memory: failed to allocate memory for comp %x.",
comp_err(dev, "mod_alloc: failed to allocate memory for comp %x.",
dev_comp_id(dev));
rfree(container);
Copy link
Collaborator

Choose a reason for hiding this comment

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

a proposal for a future improvement: I think we'll be doing lots of module-managed allocating and freeing, so maybe a pool of container objects would make sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Reserving only couple of words long containers separately from heap is very inefficient. I'll do that as a follow up

return NULL;
}
/* Store reference to allocated memory */
container->ptr = ptr;
container->size = size;
list_item_prepend(&container->mem_list, &mod->priv.memory.mem_list);

return ptr;
}
EXPORT_SYMBOL(mod_alloc_align);

/**
* Allocates memory block for module.
* @param mod Pointer to module this memory block is allocated for.
* @param bytes Size in bytes.
* @return Pointer to the allocated memory or NULL if failed.
*
* Like mod_alloc_align() but the alignment can not be specified. However,
* rballoc() will always aligns the memory to PLATFORM_DCACHE_ALIGN.
*/
void *mod_alloc(struct processing_module *mod, uint32_t size)
{
return mod_alloc_align(mod, size, 0);
}
EXPORT_SYMBOL(mod_alloc);

int module_free_memory(struct processing_module *mod, void *ptr)
/**
* Allocates memory block for module and initializes it to zero.
* @param mod Pointer to module this memory block is allocated for.
* @param bytes Size in bytes.
* @return Pointer to the allocated memory or NULL if failed.
*
* Like mod_alloc() but the allocated memory is initialized to zero.
*/
void *mod_zalloc(struct processing_module *mod, uint32_t size)
{
void *ret = mod_alloc(mod, size);

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

return ret;
}
EXPORT_SYMBOL(mod_zalloc);

/**
* Frees the memory block removes it from module's book keeping.
* @param mod Pointer to module this memory block was allocated for.
* @param ptr Pointer to the memory block.
*/
int mod_free(struct processing_module *mod, void *ptr)
{
struct module_memory *mem;
struct list_item *mem_list;
Expand All @@ -167,11 +218,12 @@ int module_free_memory(struct processing_module *mod, void *ptr)
}
}

comp_err(mod->dev, "module_free_memory: error: could not find memory pointed by %p",
comp_err(mod->dev, "mod_free: error: could not find memory pointed by %p",
ptr);

return -EINVAL;
}
EXPORT_SYMBOL(mod_free);

int module_prepare(struct processing_module *mod,
struct sof_source **sources, int num_of_sources,
Expand Down Expand Up @@ -343,7 +395,13 @@ int module_reset(struct processing_module *mod)
return 0;
}

void module_free_all_memory(struct processing_module *mod)
/**
* Frees all the memory allocated for this module
* @param mod Pointer to module this memory block was allocated for.
*
* This function is called automatically when the module is unloaded.
*/
void mod_free_all(struct processing_module *mod)
Copy link
Collaborator

Choose a reason for hiding this comment

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

in fact I'm wondering if mod_free_all needs to be exported at all? Modules themselves shouldn't call it, it should only be called by the framework before freeing the actual module

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Probably yes, but that change can not part of this commit, but that should be done as a separate commmit after "module_adapter: Free all module associated memory module_adapter_free()".

... but no, that is not as easy as one might think. Cadence codec API module uses mod_free_all() in reset() [1] call back. So I'll leave this as it is for the moent.

[1]

module_free_all_memory(mod);

Copy link
Collaborator

Choose a reason for hiding this comment

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

... but no, that is not as easy as one might think. Cadence codec API module uses mod_free_all() in reset() [1] call back. So I'll leave this as it is for the moent.

@jsarha this is interesting... So module and component structures aren't allocated in module-managed memory? If they were and you freed them in .reset() that would seem like a typical self-inflicted foot injury case to me

Copy link
Contributor Author

@jsarha jsarha Aug 8, 2025

Choose a reason for hiding this comment

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

Yes, that is indeed the case. It uses normal heap allocations for that and mod_alloc() for prepare etc. allocations, so it can just drop them with one call at reset. Need to sort that out at some point, but I leave it for later.

{
struct module_memory *mem;
struct list_item *mem_list;
Expand All @@ -357,6 +415,7 @@ void module_free_all_memory(struct processing_module *mod)
rfree(mem);
}
}
EXPORT_SYMBOL(mod_free_all);

int module_free(struct processing_module *mod)
{
Expand Down
29 changes: 13 additions & 16 deletions src/audio/module_adapter/module/waves/waves.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ static int waves_effect_allocate(struct processing_module *mod)
return -EINVAL;
}

waves_codec->effect = (MaxxEffect_t *)module_allocate_memory(mod,
waves_codec->effect = (MaxxEffect_t *)mod_alloc_align(mod,
waves_codec->effect_size, 16);

if (!waves_codec->effect) {
Expand Down Expand Up @@ -376,15 +376,15 @@ static int waves_effect_buffers(struct processing_module *mod)

comp_dbg(dev, "waves_effect_buffers() start");

i_buffer = module_allocate_memory(mod, waves_codec->buffer_bytes, 16);
i_buffer = mod_alloc_align(mod, waves_codec->buffer_bytes, 16);
if (!i_buffer) {
comp_err(dev, "waves_effect_buffers() failed to allocate %d bytes for i_buffer",
waves_codec->buffer_bytes);
ret = -ENOMEM;
goto err;
}

o_buffer = module_allocate_memory(mod, waves_codec->buffer_bytes, 16);
o_buffer = mod_alloc_align(mod, waves_codec->buffer_bytes, 16);
if (!o_buffer) {
comp_err(dev, "waves_effect_buffers() failed to allocate %d bytes for o_buffer",
waves_codec->buffer_bytes);
Expand All @@ -407,9 +407,9 @@ static int waves_effect_buffers(struct processing_module *mod)

err:
if (i_buffer)
module_free_memory(mod, i_buffer);
mod_free(mod, i_buffer);
if (o_buffer)
module_free_memory(mod, o_buffer);
mod_free(mod, o_buffer);
return ret;
}

Expand Down Expand Up @@ -475,13 +475,13 @@ static int waves_effect_save_config_blob_to_cache(struct processing_module *mod,
/* release old cached config blob*/
if (waves_codec->config_blob && size != waves_codec->config_blob_size) {
comp_info(dev, "waves_effect_save_config_blob_to_cache() release blob");
module_free_memory(mod, waves_codec->config_blob);
mod_free(mod, waves_codec->config_blob);
waves_codec->config_blob = NULL;
waves_codec->config_blob_size = 0;
}

if (!waves_codec->config_blob) {
waves_codec->config_blob = module_allocate_memory(mod, size, 16);
waves_codec->config_blob = mod_alloc_align(mod, size, 16);
if (!waves_codec->config_blob) {
comp_err(dev,
"waves_effect_save_config_blob_to_cache() failed to allocate %d bytes for config blob",
Expand All @@ -497,7 +497,7 @@ static int waves_effect_save_config_blob_to_cache(struct processing_module *mod,
comp_err(dev,
"waves_effect_save_config_blob_to_cache(): failed to copy config blob %d",
ret);
module_free_memory(mod, waves_codec->config_blob);
mod_free(mod, waves_codec->config_blob);
waves_codec->config_blob = NULL;
waves_codec->config_blob_size = 0;
return ret;
Expand Down Expand Up @@ -668,7 +668,7 @@ static int waves_codec_init(struct processing_module *mod)

comp_dbg(dev, "waves_codec_init() start");

waves_codec = module_allocate_memory(mod, sizeof(struct waves_codec_data), 16);
waves_codec = mod_alloc_align(mod, sizeof(struct waves_codec_data), 16);
if (!waves_codec) {
comp_err(dev, "waves_codec_init() failed to allocate %d bytes for waves_codec_data",
sizeof(struct waves_codec_data));
Expand All @@ -677,10 +677,8 @@ static int waves_codec_init(struct processing_module *mod)
memset(waves_codec, 0, sizeof(struct waves_codec_data));
codec->private = waves_codec;
ret = waves_effect_allocate(mod);
if (ret) {
module_free_memory(mod, waves_codec);
if (ret)
codec->private = NULL;
}
}

if (ret) {
Expand All @@ -696,7 +694,7 @@ static int waves_codec_init(struct processing_module *mod)
return -EINVAL;
}

response = module_allocate_memory(mod, waves_codec->response_max_bytes, 16);
response = mod_alloc_align(mod, waves_codec->response_max_bytes, 16);
if (!response) {
comp_err(dev, "waves_codec_init() failed to allocate %d bytes for response",
waves_codec->response_max_bytes);
Expand Down Expand Up @@ -850,10 +848,10 @@ static int waves_codec_reset(struct processing_module *mod)
comp_err(dev, "waves_codec_reset() failed %d", ret);

if (codec->mpd.in_buff)
module_free_memory(mod, codec->mpd.in_buff);
mod_free(mod, codec->mpd.in_buff);

if (codec->mpd.out_buff)
module_free_memory(mod, codec->mpd.out_buff);
mod_free(mod, codec->mpd.out_buff);

waves_codec->initialized = false;
comp_dbg(dev, "waves_codec_reset() done");
Expand All @@ -862,7 +860,6 @@ static int waves_codec_reset(struct processing_module *mod)

static int waves_codec_free(struct processing_module *mod)
{
module_free_all_memory(mod);
comp_dbg(mod->dev, "waves_codec_free()");
return 0;
}
Expand Down
17 changes: 17 additions & 0 deletions src/audio/module_adapter/module_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,8 @@ void module_adapter_free(struct comp_dev *dev)
buffer_free(buffer);
}

mod_free_all(mod);

#if CONFIG_IPC_MAJOR_4
rfree(mod->priv.cfg.input_pins);
#endif
Expand All @@ -1232,6 +1234,21 @@ void module_adapter_free(struct comp_dev *dev)
}
EXPORT_SYMBOL(module_adapter_free);

size_t module_adapter_heap_usage(struct processing_module *mod)
{
struct list_item *mem_list, *_mem_list;
size_t size = 0;

list_for_item_safe(mem_list, _mem_list, &mod->priv.memory.mem_list) {
struct module_memory *mem = container_of(mem_list, struct module_memory, mem_list);

size += mem->size;
}

return size;
}
EXPORT_SYMBOL(module_adapter_heap_usage);

/*
* \brief Get DAI hw params
* \param[in] dev - component device pointer
Expand Down
2 changes: 1 addition & 1 deletion src/audio/src/src.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static int src_prepare(struct processing_module *mod,
if (ret < 0)
return ret;

ret = src_allocate_copy_stages(mod->dev, a,
ret = src_allocate_copy_stages(mod, a,
src_table1[a->idx_out][a->idx_in],
src_table2[a->idx_out][a->idx_in]);
if (ret < 0)
Expand Down
Loading
Loading