From 065e8ee2c022e2f421a9772fbde20583885d0836 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 24 Jul 2025 20:23:34 +0300 Subject: [PATCH 01/12] modules: Rename module_allocate_memory and module_free_memory Rename module_allocate_memory and module_free_memory to mod_alloc and mod_free. Signed-off-by: Jyri Sarha --- src/audio/codec/dts/dts.c | 6 ++--- src/audio/module_adapter/module/cadence.c | 14 +++++----- src/audio/module_adapter/module/generic.c | 14 +++++----- src/audio/module_adapter/module/waves/waves.c | 26 +++++++++---------- .../sof/audio/module_adapter/module/generic.h | 4 +-- 5 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/audio/codec/dts/dts.c b/src/audio/codec/dts/dts.c index 83a112ab0ae3..97a60f7ca98c 100644 --- a/src/audio/codec/dts/dts.c +++ b/src/audio/codec/dts/dts.c @@ -25,7 +25,7 @@ static void *dts_effect_allocate_codec_memory(void *mod_void, unsigned int lengt comp_dbg(dev, "dts_effect_allocate_codec_memory() start"); - pMem = module_allocate_memory(mod, (uint32_t)length, (uint32_t)alignment); + pMem = mod_alloc(mod, (uint32_t)length, (uint32_t)alignment); if (pMem == NULL) comp_err(dev, @@ -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"); } diff --git a/src/audio/module_adapter/module/cadence.c b/src/audio/module_adapter/module/cadence.c index 87ee611eb19f..61e0daa39bc3 100644 --- a/src/audio/module_adapter/module/cadence.c +++ b/src/audio/module_adapter/module/cadence.c @@ -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(mod, mem_size, mem_alignment); if (!ptr) { comp_err(dev, "init_memory_tables() error %x: failed to allocate memory for %d", ret, mem_type); @@ -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; } @@ -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, 4); if (!cd->mem_tabs) { comp_err(dev, "cadence_codec_prepare() error: failed to allocate space for memtabs"); return -ENOMEM; @@ -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; } diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index f7983cf67d53..07463a47c11f 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -110,14 +110,14 @@ int module_init(struct processing_module *mod) return 0; } -void *module_allocate_memory(struct processing_module *mod, uint32_t size, uint32_t alignment) +void *mod_alloc(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."); return NULL; } @@ -125,7 +125,7 @@ void *module_allocate_memory(struct processing_module *mod, uint32_t size, uint3 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; } @@ -136,7 +136,7 @@ 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)); return NULL; } @@ -146,8 +146,9 @@ void *module_allocate_memory(struct processing_module *mod, uint32_t size, uint3 return ptr; } +EXPORT_SYMBOL(mod_alloc); -int module_free_memory(struct processing_module *mod, void *ptr) +int mod_free(struct processing_module *mod, void *ptr) { struct module_memory *mem; struct list_item *mem_list; @@ -167,11 +168,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, diff --git a/src/audio/module_adapter/module/waves/waves.c b/src/audio/module_adapter/module/waves/waves.c index d384b2b15334..b685c92e9967 100644 --- a/src/audio/module_adapter/module/waves/waves.c +++ b/src/audio/module_adapter/module/waves/waves.c @@ -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(mod, waves_codec->effect_size, 16); if (!waves_codec->effect) { @@ -376,7 +376,7 @@ 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(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); @@ -384,7 +384,7 @@ static int waves_effect_buffers(struct processing_module *mod) goto err; } - o_buffer = module_allocate_memory(mod, waves_codec->buffer_bytes, 16); + o_buffer = mod_alloc(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); @@ -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; } @@ -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(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", @@ -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; @@ -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(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)); @@ -678,7 +678,7 @@ static int waves_codec_init(struct processing_module *mod) codec->private = waves_codec; ret = waves_effect_allocate(mod); if (ret) { - module_free_memory(mod, waves_codec); + mod_free(mod, waves_codec); codec->private = NULL; } } @@ -696,7 +696,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(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); @@ -850,10 +850,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"); diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index bff6aa420629..1793afa3e463 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -153,8 +153,8 @@ struct module_processing_data { /*****************************************************************************/ int module_load_config(struct comp_dev *dev, const void *cfg, size_t size); int module_init(struct processing_module *mod); -void *module_allocate_memory(struct processing_module *mod, uint32_t size, uint32_t alignment); -int module_free_memory(struct processing_module *mod, void *ptr); +void *mod_alloc(struct processing_module *mod, uint32_t size, uint32_t alignment); +int mod_free(struct processing_module *mod, void *ptr); void module_free_all_memory(struct processing_module *mod); int module_prepare(struct processing_module *mod, struct sof_source **sources, int num_of_sources, From 9ce978565d7ca31c285ccba6bc46a3ed529851ba Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 31 Jul 2025 20:21:24 +0300 Subject: [PATCH 02/12] modules: Rename module_free_all_memory() to mod_free_all() Rename module_free_all_memory() to mod_free_all(). Signed-off-by: Jyri Sarha --- src/audio/codec/dts/dts.c | 2 +- src/audio/module_adapter/module/cadence.c | 4 ++-- src/audio/module_adapter/module/generic.c | 3 ++- src/audio/module_adapter/module/waves/waves.c | 2 +- src/include/sof/audio/module_adapter/module/generic.h | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/audio/codec/dts/dts.c b/src/audio/codec/dts/dts.c index 97a60f7ca98c..bf1b2e8cfba4 100644 --- a/src/audio/codec/dts/dts.c +++ b/src/audio/codec/dts/dts.c @@ -405,7 +405,7 @@ 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); + mod_free_all(mod); comp_dbg(dev, "dts_codec_free() done"); diff --git a/src/audio/module_adapter/module/cadence.c b/src/audio/module_adapter/module/cadence.c index 61e0daa39bc3..237d9c6e85e9 100644 --- a/src/audio/module_adapter/module/cadence.c +++ b/src/audio/module_adapter/module/cadence.c @@ -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); @@ -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; diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index 07463a47c11f..b0061403f802 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -345,7 +345,7 @@ int module_reset(struct processing_module *mod) return 0; } -void module_free_all_memory(struct processing_module *mod) +void mod_free_all(struct processing_module *mod) { struct module_memory *mem; struct list_item *mem_list; @@ -359,6 +359,7 @@ void module_free_all_memory(struct processing_module *mod) rfree(mem); } } +EXPORT_SYMBOL(mod_free_all); int module_free(struct processing_module *mod) { diff --git a/src/audio/module_adapter/module/waves/waves.c b/src/audio/module_adapter/module/waves/waves.c index b685c92e9967..f65c1985fed0 100644 --- a/src/audio/module_adapter/module/waves/waves.c +++ b/src/audio/module_adapter/module/waves/waves.c @@ -862,7 +862,7 @@ static int waves_codec_reset(struct processing_module *mod) static int waves_codec_free(struct processing_module *mod) { - module_free_all_memory(mod); + mod_free_all(mod); comp_dbg(mod->dev, "waves_codec_free()"); return 0; } diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 1793afa3e463..19acc876fce6 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -155,7 +155,7 @@ int module_load_config(struct comp_dev *dev, const void *cfg, size_t size); int module_init(struct processing_module *mod); void *mod_alloc(struct processing_module *mod, uint32_t size, uint32_t alignment); int mod_free(struct processing_module *mod, void *ptr); -void module_free_all_memory(struct processing_module *mod); +void mod_free_all(struct processing_module *mod); int module_prepare(struct processing_module *mod, struct sof_source **sources, int num_of_sources, struct sof_sink **sinks, int num_of_sinks); From 90c9ffe182bb32e48f499ac7541f8e95fd7652c2 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 29 Jul 2025 16:00:41 +0300 Subject: [PATCH 03/12] modules: Fix mod_alloc() error branch memory leak Container memory should be freed if the requested memory allocation fails. Signed-off-by: Jyri Sarha --- src/audio/module_adapter/module/generic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index b0061403f802..ae8f490e5c54 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -138,6 +138,7 @@ void *mod_alloc(struct processing_module *mod, uint32_t size, uint32_t alignment if (!ptr) { comp_err(dev, "mod_alloc: failed to allocate memory for comp %x.", dev_comp_id(dev)); + rfree(container); return NULL; } /* Store reference to allocated memory */ From 59b7fe7240ff17ed5660742170d89520ce1f9e40 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Mon, 28 Jul 2025 18:22:42 +0300 Subject: [PATCH 04/12] modules: Add mod_zalloc() function Add mod_zalloc() function that is otherwise the same as mod_alloc(), but allocated memory is initialized to zero. Signed-off-by: Jyri Sarha --- src/audio/module_adapter/module/generic.c | 11 +++++++++++ src/include/sof/audio/module_adapter/module/generic.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index ae8f490e5c54..104f30bae1bc 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -149,6 +149,17 @@ void *mod_alloc(struct processing_module *mod, uint32_t size, uint32_t alignment } EXPORT_SYMBOL(mod_alloc); +void *mod_zalloc(struct processing_module *mod, uint32_t size, uint32_t alignment) +{ + void *ret = mod_alloc(mod, size, alignment); + + if (ret) + memset(ret, 0, size); + + return ret; +} +EXPORT_SYMBOL(mod_zalloc); + int mod_free(struct processing_module *mod, void *ptr) { struct module_memory *mem; diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 19acc876fce6..008851b7db86 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -154,6 +154,7 @@ struct module_processing_data { int module_load_config(struct comp_dev *dev, const void *cfg, size_t size); int module_init(struct processing_module *mod); void *mod_alloc(struct processing_module *mod, uint32_t size, uint32_t alignment); +void *mod_zalloc(struct processing_module *mod, uint32_t size, uint32_t alignment); int mod_free(struct processing_module *mod, void *ptr); void mod_free_all(struct processing_module *mod); int module_prepare(struct processing_module *mod, From df29ba2ad325184ef7be4ff05b3b41dd644fc5d6 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 31 Jul 2025 20:32:37 +0300 Subject: [PATCH 05/12] module_adapter: Free all module associated memory module_adapter_free() Free all module associated memory module_adapter_free() by calling mod_free_all(). Signed-off-by: Jyri Sarha --- src/audio/module_adapter/module_adapter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index 45dab7b02e19..bd122348868d 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -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 From 9d894fb6f87e8aa041a04ac4f4c23ce76a8a2212 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 31 Jul 2025 19:25:21 +0300 Subject: [PATCH 06/12] modules: Drop alignment from mod_alloc() and introduce mod_alloc_align() Drop alignment argument from mod_alloc() and introduce mod_alloc_align() and apply all the necessary changes to mod_alloc() calls. Also adds Doxygen documentation to mod_alloc_align, mod_alloc, mod_zalloc, mod_free, and mod_free_all. Signed-off-by: Jyri Sarha --- src/audio/codec/dts/dts.c | 2 +- src/audio/module_adapter/module/cadence.c | 4 +- src/audio/module_adapter/module/generic.c | 49 +++++++++++++++++-- src/audio/module_adapter/module/waves/waves.c | 12 ++--- .../sof/audio/module_adapter/module/generic.h | 5 +- 5 files changed, 58 insertions(+), 14 deletions(-) diff --git a/src/audio/codec/dts/dts.c b/src/audio/codec/dts/dts.c index bf1b2e8cfba4..37a1d82bb215 100644 --- a/src/audio/codec/dts/dts.c +++ b/src/audio/codec/dts/dts.c @@ -25,7 +25,7 @@ static void *dts_effect_allocate_codec_memory(void *mod_void, unsigned int lengt comp_dbg(dev, "dts_effect_allocate_codec_memory() start"); - pMem = mod_alloc(mod, (uint32_t)length, (uint32_t)alignment); + pMem = mod_alloc_align(mod, (uint32_t)length, (uint32_t)alignment); if (pMem == NULL) comp_err(dev, diff --git a/src/audio/module_adapter/module/cadence.c b/src/audio/module_adapter/module/cadence.c index 237d9c6e85e9..c854fc2fb85b 100644 --- a/src/audio/module_adapter/module/cadence.c +++ b/src/audio/module_adapter/module/cadence.c @@ -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 = mod_alloc(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); @@ -688,7 +688,7 @@ static int cadence_codec_prepare(struct processing_module *mod, return ret; } - cd->mem_tabs = mod_alloc(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; diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index 104f30bae1bc..313b29f504e6 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -110,7 +110,16 @@ int module_init(struct processing_module *mod) return 0; } -void *mod_alloc(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; @@ -147,11 +156,34 @@ void *mod_alloc(struct processing_module *mod, uint32_t size, uint32_t alignment 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); -void *mod_zalloc(struct processing_module *mod, uint32_t size, uint32_t alignment) +/** + * 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, alignment); + void *ret = mod_alloc(mod, size); if (ret) memset(ret, 0, size); @@ -160,6 +192,11 @@ void *mod_zalloc(struct processing_module *mod, uint32_t size, uint32_t alignmen } 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; @@ -357,6 +394,12 @@ int module_reset(struct processing_module *mod) return 0; } +/** + * 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) { struct module_memory *mem; diff --git a/src/audio/module_adapter/module/waves/waves.c b/src/audio/module_adapter/module/waves/waves.c index f65c1985fed0..f88a73ea5a96 100644 --- a/src/audio/module_adapter/module/waves/waves.c +++ b/src/audio/module_adapter/module/waves/waves.c @@ -200,7 +200,7 @@ static int waves_effect_allocate(struct processing_module *mod) return -EINVAL; } - waves_codec->effect = (MaxxEffect_t *)mod_alloc(mod, + waves_codec->effect = (MaxxEffect_t *)mod_alloc_align(mod, waves_codec->effect_size, 16); if (!waves_codec->effect) { @@ -376,7 +376,7 @@ static int waves_effect_buffers(struct processing_module *mod) comp_dbg(dev, "waves_effect_buffers() start"); - i_buffer = mod_alloc(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); @@ -384,7 +384,7 @@ static int waves_effect_buffers(struct processing_module *mod) goto err; } - o_buffer = mod_alloc(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); @@ -481,7 +481,7 @@ static int waves_effect_save_config_blob_to_cache(struct processing_module *mod, } if (!waves_codec->config_blob) { - waves_codec->config_blob = mod_alloc(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", @@ -668,7 +668,7 @@ static int waves_codec_init(struct processing_module *mod) comp_dbg(dev, "waves_codec_init() start"); - waves_codec = mod_alloc(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)); @@ -696,7 +696,7 @@ static int waves_codec_init(struct processing_module *mod) return -EINVAL; } - response = mod_alloc(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); diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 008851b7db86..f2483a11909c 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -153,8 +153,9 @@ struct module_processing_data { /*****************************************************************************/ int module_load_config(struct comp_dev *dev, const void *cfg, size_t size); int module_init(struct processing_module *mod); -void *mod_alloc(struct processing_module *mod, uint32_t size, uint32_t alignment); -void *mod_zalloc(struct processing_module *mod, uint32_t size, uint32_t alignment); +void *mod_alloc_align(struct processing_module *mod, uint32_t size, uint32_t alignment); +void *mod_alloc(struct processing_module *mod, uint32_t size); +void *mod_zalloc(struct processing_module *mod, uint32_t size); int mod_free(struct processing_module *mod, void *ptr); void mod_free_all(struct processing_module *mod); int module_prepare(struct processing_module *mod, From bf99df987f2b4099832f8a4343417bd35c0aea61 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Mon, 4 Aug 2025 21:36:31 +0300 Subject: [PATCH 07/12] modules: Remove redundant mod_free() and mod_free_all() calls Remove redundant mod_free() and mod_free_all() calls. The calls became redundant after mod_free_all() was added to module_adapter_free(). This change concerns only the modules that are already exclusively using mod_alloc() and friends from module API. Namely, Cadence Codec API (sof/audio/module_adapter/module/cadence.c) was left out even thou it uses mod_alloc() and friends, since it still also uses direct rballoc(), rzalloc(), rmalloc(), and rfree() calls. Cadence Codec API will be dealt with the rest of the modules that do not yet use module heap API. Signed-off-by: Jyri Sarha --- src/audio/codec/dts/dts.c | 2 -- src/audio/module_adapter/module/waves/waves.c | 5 +---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/audio/codec/dts/dts.c b/src/audio/codec/dts/dts.c index 37a1d82bb215..cdda17b78d66 100644 --- a/src/audio/codec/dts/dts.c +++ b/src/audio/codec/dts/dts.c @@ -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); - mod_free_all(mod); - comp_dbg(dev, "dts_codec_free() done"); return ret; diff --git a/src/audio/module_adapter/module/waves/waves.c b/src/audio/module_adapter/module/waves/waves.c index f88a73ea5a96..94151a0f8a6d 100644 --- a/src/audio/module_adapter/module/waves/waves.c +++ b/src/audio/module_adapter/module/waves/waves.c @@ -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) { - mod_free(mod, waves_codec); + if (ret) codec->private = NULL; - } } if (ret) { @@ -862,7 +860,6 @@ static int waves_codec_reset(struct processing_module *mod) static int waves_codec_free(struct processing_module *mod) { - mod_free_all(mod); comp_dbg(mod->dev, "waves_codec_free()"); return 0; } From e6962ffecbcac16aabd4cd654fd989ac0e881a13 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 1 Aug 2025 16:03:07 +0300 Subject: [PATCH 08/12] module_adapter: Add module_adapter_heap_usage() Adds exported module_adapter_heap_usage() function that returns current heap usage of the module in question. Signed-off-by: Jyri Sarha --- src/audio/module_adapter/module/generic.c | 1 + src/audio/module_adapter/module_adapter.c | 15 +++++++++++++++ .../sof/audio/module_adapter/module/generic.h | 3 +++ 3 files changed, 19 insertions(+) diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index 313b29f504e6..b755de0adf16 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -152,6 +152,7 @@ void *mod_alloc_align(struct processing_module *mod, uint32_t size, uint32_t ali } /* Store reference to allocated memory */ container->ptr = ptr; + container->size = size; list_item_prepend(&container->mem_list, &mod->priv.memory.mem_list); return ptr; diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index bd122348868d..0f2b624e0431 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -1234,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 diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index f2483a11909c..395fe771da39 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -122,6 +122,7 @@ struct module_param { struct module_memory { void *ptr; /**< A pointr to particular memory block */ struct list_item mem_list; /**< list of memory allocated by module */ + size_t size; }; /** @@ -219,6 +220,8 @@ int module_adapter_trigger(struct comp_dev *dev, int cmd); void module_adapter_free(struct comp_dev *dev); int module_adapter_reset(struct comp_dev *dev); +size_t module_adapter_heap_usage(struct processing_module *mod); + #if CONFIG_IPC_MAJOR_3 static inline int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value) From dd1f009622f8789f0b71982527b2d3e81eacab62 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 1 Aug 2025 16:24:24 +0300 Subject: [PATCH 09/12] zephyr: shell: Fix implicit declaration of function 'strtol' Fix implicit declaration of function 'strtol' by including stdlib.h. Signed-off-by: Jyri Sarha --- zephyr/sof_shell.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/zephyr/sof_shell.c b/zephyr/sof_shell.c index d36344b1b3fe..1e884bc8cf99 100644 --- a/zephyr/sof_shell.c +++ b/zephyr/sof_shell.c @@ -12,6 +12,8 @@ #include #include +#include + #define SOF_TEST_INJECT_SCHED_GAP_USEC 1500 static int cmd_sof_test_inject_sched_gap(const struct shell *sh, From 7b2e881317ddb5a2a33aacc5804d0dfc4b6593ae Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Mon, 4 Aug 2025 23:57:59 +0300 Subject: [PATCH 10/12] include: ll_schedule_domain: Fix struct comp_dev related warnings Declare struct comp_dev to avoid warnings if ll_schedule_domain.h is included before struct comp_dev is defined. Signed-off-by: Jyri Sarha --- src/include/sof/schedule/ll_schedule_domain.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/sof/schedule/ll_schedule_domain.h b/src/include/sof/schedule/ll_schedule_domain.h index be8dcb477ce8..5fc7691e3b13 100644 --- a/src/include/sof/schedule/ll_schedule_domain.h +++ b/src/include/sof/schedule/ll_schedule_domain.h @@ -35,6 +35,7 @@ struct dma; struct ll_schedule_domain; struct task; struct timer; +struct comp_dev; struct ll_schedule_domain_ops { int (*domain_register)(struct ll_schedule_domain *domain, From 5832ea5df9ad41fb87d79fb211006dc422371e05 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 31 Jul 2025 16:47:06 +0300 Subject: [PATCH 11/12] zephyr: shell: Add sof module_heap_usage command Adds new command to sof sub-command set. The new command, module_heap_usage, prints out all active component ids, their heap memory usage allocated through module API, and configured maximum heap size. NOTE: For the moment there is nothing preventing a module from allocating more memory than the configured maximum. Signed-off-by: Jyri Sarha --- zephyr/sof_shell.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/zephyr/sof_shell.c b/zephyr/sof_shell.c index 1e884bc8cf99..60785c4eb5c4 100644 --- a/zephyr/sof_shell.c +++ b/zephyr/sof_shell.c @@ -7,6 +7,7 @@ #include /* sof_get() */ #include +#include #include #include @@ -41,11 +42,39 @@ static int cmd_sof_test_inject_sched_gap(const struct shell *sh, return 0; } +static int cmd_sof_module_heap_usage(const struct shell *sh, + size_t argc, char *argv[]) +{ + struct ipc *ipc = sof_get()->ipc; + struct list_item *clist, *_clist; + struct ipc_comp_dev *icd; + + if (!ipc) { + shell_print(sh, "No IPC"); + return 0; + } + + list_for_item_safe(clist, _clist, &ipc->comp_list) { + icd = container_of(clist, struct ipc_comp_dev, list); + if (icd->type != COMP_TYPE_COMPONENT) + continue; + + shell_print(sh, "comp id 0x%08x\t%8zu bytes\t(%zu max)", icd->id, + module_adapter_heap_usage(comp_mod(icd->cd)), + comp_mod(icd->cd)->priv.cfg.heap_bytes); + } + return 0; +} + SHELL_STATIC_SUBCMD_SET_CREATE(sof_commands, SHELL_CMD(test_inject_sched_gap, NULL, "Inject a gap to audio scheduling\n", cmd_sof_test_inject_sched_gap), + SHELL_CMD(module_heap_usage, NULL, + "Print heap memory usage of each module\n", + cmd_sof_module_heap_usage), + SHELL_SUBCMD_SET_END ); From cb0f95b18484c18fc9cb45b1f3229783b3e79879 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Mon, 28 Jul 2025 21:54:11 +0300 Subject: [PATCH 12/12] Audio: SRC: All memory allocations through module Change all memory allocations to go through module API mod_alloc(), mod_zalloc(), and mod_free(). The mod_free() calls are dropped form error handling branches and from src_free() as the memory is anyway freed as the module should unload shortly. Signed-off-by: Jyri Sarha --- src/audio/src/src.c | 2 +- src/audio/src/src_common.c | 24 ++++++++---------------- src/audio/src/src_common.h | 2 +- src/audio/src/src_ipc3.c | 2 +- src/audio/src/src_ipc4.c | 3 +-- src/audio/src/src_lite.c | 2 +- 6 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/audio/src/src.c b/src/audio/src/src.c index c891e97fae4d..7f744f64d43d 100644 --- a/src/audio/src/src.c +++ b/src/audio/src/src.c @@ -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) diff --git a/src/audio/src/src_common.c b/src/audio/src/src_common.c index 120077f5763b..37e0b6585765 100644 --- a/src/audio/src/src_common.c +++ b/src/audio/src/src_common.c @@ -531,9 +531,9 @@ int src_params_general(struct processing_module *mod, } /* free any existing delay lines. TODO reuse if same size */ - rfree(cd->delay_lines); + mod_free(mod, cd->delay_lines); - cd->delay_lines = rballoc(SOF_MEM_FLAG_USER, delay_lines_size); + cd->delay_lines = mod_alloc(mod, delay_lines_size); if (!cd->delay_lines) { comp_err(dev, "src_params(): failed to alloc cd->delay_lines, delay_lines_size = %zu", delay_lines_size); @@ -594,7 +594,7 @@ int src_param_set(struct comp_dev *dev, struct comp_data *cd) return 0; } -int src_allocate_copy_stages(struct comp_dev *dev, struct src_param *prm, +int src_allocate_copy_stages(struct processing_module *mod, struct src_param *prm, const struct src_stage *stage_src1, const struct src_stage *stage_src2) { @@ -607,10 +607,9 @@ int src_allocate_copy_stages(struct comp_dev *dev, struct src_param *prm, size_t tap_size = sizeof(int32_t); #endif - stage_dst = rmalloc(SOF_MEM_FLAG_USER, - 2 * sizeof(*stage_dst)); + stage_dst = mod_alloc(mod, 2 * sizeof(*stage_dst)); if (!stage_dst) { - comp_err(dev, "failed to allocate stages"); + comp_err(mod->dev, "failed to allocate stages"); return -ENOMEM; } @@ -622,10 +621,9 @@ int src_allocate_copy_stages(struct comp_dev *dev, struct src_param *prm, coef_size[1] = tap_size * stage_src2->filter_length; if (coef_size[0] == 0 || coef_size[1] == 0) { - comp_err(dev, + comp_err(mod->dev, "illegal zero coefficient vector size for unsupported conversion request %d to %d", prm->in_fs[prm->idx_in], prm->out_fs[prm->idx_out]); - rfree(stage_dst); return -EINVAL; } @@ -633,9 +631,8 @@ int src_allocate_copy_stages(struct comp_dev *dev, struct src_param *prm, stage_dst[1].coefs = fast_get(stage_src2->coefs, coef_size[1]); if (!stage_dst[0].coefs || !stage_dst[1].coefs) { - comp_err(dev, "failed to allocate coefficients"); + comp_err(mod->dev, "failed to allocate coefficients"); fast_put(stage_dst[0].coefs); - rfree(stage_dst); return -ENOMEM; } @@ -707,21 +704,16 @@ int src_reset(struct processing_module *mod) __cold int src_free(struct processing_module *mod) { - struct comp_data *cd = module_get_private_data(mod); - assert_can_be_cold(); comp_info(mod->dev, "src_free()"); - /* Free dynamically reserved buffers for SRC algorithm */ - rfree(cd->delay_lines); #if CONFIG_FAST_GET + struct comp_data *cd = module_get_private_data(mod); if (cd->param.stage1) { fast_put(cd->param.stage1->coefs); fast_put(cd->param.stage2->coefs); } - rfree((void *)cd->param.stage1); #endif - rfree(cd); return 0; } diff --git a/src/audio/src/src_common.h b/src/audio/src/src_common.h index 56b07a0b03a2..6a8028662ffd 100644 --- a/src/audio/src/src_common.h +++ b/src/audio/src/src_common.h @@ -215,7 +215,7 @@ static inline int src_fallback(struct comp_data *cd, return 0; } -int src_allocate_copy_stages(struct comp_dev *dev, struct src_param *prm, +int src_allocate_copy_stages(struct processing_module *mod, struct src_param *prm, const struct src_stage *stage_src1, const struct src_stage *stage_src2); int src_rate_check(const void *spec); diff --git a/src/audio/src/src_ipc3.c b/src/audio/src/src_ipc3.c index 93b0348ba462..75b74d1e257f 100644 --- a/src/audio/src/src_ipc3.c +++ b/src/audio/src/src_ipc3.c @@ -178,7 +178,7 @@ int src_init(struct processing_module *mod) return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; diff --git a/src/audio/src/src_ipc4.c b/src/audio/src/src_ipc4.c index 76ef1a50175c..0786ced3306b 100644 --- a/src/audio/src/src_ipc4.c +++ b/src/audio/src/src_ipc4.c @@ -209,7 +209,7 @@ __cold int src_init(struct processing_module *mod) return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; @@ -240,7 +240,6 @@ __cold int src_init(struct processing_module *mod) default: comp_err(dev, "src_init(): Illegal sample depth %d", cd->ipc_config.base.audio_fmt.depth); - rfree(cd); return -EINVAL; } diff --git a/src/audio/src/src_lite.c b/src/audio/src/src_lite.c index 75f664ec262d..4cbedea76ad2 100644 --- a/src/audio/src/src_lite.c +++ b/src/audio/src/src_lite.c @@ -43,7 +43,7 @@ static int src_lite_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)