From fcfbeae027c3b88d1789fa8051c97c77547e9252 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 27 Jan 2026 14:24:39 +0100 Subject: [PATCH] Reapply "audio: module-adapter: use objpool for allocation containers" This reverts commit 6d2d581472e5a4b15e506ba60fb70d31b09176eb. Using an object pool for module allocation containers should now work again. Signed-off-by: Guennadi Liakhovetski --- posix/include/rtos/alloc.h | 5 +- src/audio/module_adapter/module/generic.c | 117 ++++++------------ .../sof/audio/module_adapter/module/generic.h | 7 +- src/platform/library/lib/alloc.c | 5 + test/cmocka/src/audio/eq_fir/CMakeLists.txt | 1 + test/cmocka/src/audio/eq_iir/CMakeLists.txt | 1 + test/cmocka/src/audio/mixer/CMakeLists.txt | 1 + test/cmocka/src/audio/mux/CMakeLists.txt | 1 + test/cmocka/src/audio/volume/CMakeLists.txt | 1 + test/cmocka/src/common_mocks.c | 5 + zephyr/lib/alloc.c | 2 - 11 files changed, 60 insertions(+), 86 deletions(-) diff --git a/posix/include/rtos/alloc.h b/posix/include/rtos/alloc.h index 424a6d520cfa..b8efac0d3112 100644 --- a/posix/include/rtos/alloc.h +++ b/posix/include/rtos/alloc.h @@ -140,10 +140,7 @@ static inline void k_heap_init(struct k_heap *heap, void *mem, size_t bytes) void *sof_heap_alloc(struct k_heap *heap, uint32_t flags, size_t bytes, size_t alignment); void sof_heap_free(struct k_heap *heap, void *addr); -static inline struct k_heap *sof_sys_heap_get(void) -{ - return NULL; -} +struct k_heap *sof_sys_heap_get(void); /** * Calculates length of the null-terminated string. diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index d2b86bb40d08..f9bf5d52bef3 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -12,6 +12,8 @@ */ #include +#include +#include #include #include #include @@ -81,10 +83,10 @@ int module_load_config(struct comp_dev *dev, const void *cfg, size_t size) void mod_resource_init(struct processing_module *mod) { struct module_data *md = &mod->priv; + /* Init memory list */ - list_init(&md->resources.res_list); - list_init(&md->resources.free_cont_list); - list_init(&md->resources.cont_chunk_list); + list_init(&md->resources.objpool.list); + md->resources.objpool.heap = md->resources.heap; md->resources.heap_usage = 0; md->resources.heap_high_water_mark = 0; } @@ -141,43 +143,14 @@ int module_init(struct processing_module *mod) return 0; } -struct container_chunk { - struct list_item chunk_list; - struct module_resource containers[CONFIG_MODULE_MEMORY_API_CONTAINER_CHUNK_SIZE]; -}; - static struct module_resource *container_get(struct processing_module *mod) { - struct module_resources *res = &mod->priv.resources; - struct k_heap *mod_heap = res->heap; - struct module_resource *container; - - if (list_is_empty(&res->free_cont_list)) { - struct container_chunk *chunk = sof_heap_alloc(mod_heap, 0, sizeof(*chunk), 0); - int i; - - if (!chunk) { - comp_err(mod->dev, "allocating more containers failed"); - return NULL; - } - - memset(chunk, 0, sizeof(*chunk)); - - list_item_append(&chunk->chunk_list, &res->cont_chunk_list); - for (i = 0; i < ARRAY_SIZE(chunk->containers); i++) - list_item_append(&chunk->containers[i].list, &res->free_cont_list); - } - - container = list_first_item(&res->free_cont_list, struct module_resource, list); - list_item_del(&container->list); - return container; + return objpool_alloc(&mod->priv.resources.objpool, sizeof(struct module_resource), 0); } static void container_put(struct processing_module *mod, struct module_resource *container) { - struct module_resources *res = &mod->priv.resources; - - list_item_append(&container->list, &res->free_cont_list); + objpool_free(&mod->priv.resources.objpool, container); } #if CONFIG_USERSPACE @@ -235,7 +208,6 @@ void *mod_balloc_align(struct processing_module *mod, size_t size, size_t alignm container->ptr = ptr; container->size = size; container->type = MOD_RES_HEAP; - list_item_prepend(&container->list, &res->res_list); res->heap_usage += size; if (res->heap_usage > res->heap_high_water_mark) @@ -286,7 +258,6 @@ void *z_impl_mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t container->ptr = ptr; container->size = size; container->type = MOD_RES_HEAP; - list_item_prepend(&container->list, &res->res_list); res->heap_usage += size; if (res->heap_usage > res->heap_high_water_mark) @@ -306,7 +277,7 @@ EXPORT_SYMBOL(z_impl_mod_alloc_ext); #if CONFIG_COMP_BLOB struct comp_data_blob_handler *mod_data_blob_handler_new(struct processing_module *mod) { - struct module_resources *res = &mod->priv.resources; + struct module_resources * __maybe_unused res = &mod->priv.resources; struct comp_data_blob_handler *bhp; struct module_resource *container; @@ -325,7 +296,6 @@ struct comp_data_blob_handler *mod_data_blob_handler_new(struct processing_modul container->bhp = bhp; container->size = 0; container->type = MOD_RES_BLOB_HANDLER; - list_item_prepend(&container->list, &res->res_list); return bhp; } @@ -362,7 +332,6 @@ const void *z_impl_mod_fast_get(struct processing_module *mod, const void * cons container->sram_ptr = ptr; container->size = 0; container->type = MOD_RES_FAST_GET; - list_item_prepend(&container->list, &res->res_list); return ptr; } @@ -394,6 +363,29 @@ static int free_contents(struct processing_module *mod, struct module_resource * return -EINVAL; } +struct mod_res_cb_arg { + struct processing_module *mod; + const void *ptr; +}; + +static bool mod_res_free(void *data, void *arg) +{ + struct mod_res_cb_arg *cb_arg = arg; + struct module_resource *container = data; + + if (cb_arg->ptr && container->ptr != cb_arg->ptr) + return false; + + int ret = free_contents(cb_arg->mod, container); + + if (ret < 0) + comp_err(cb_arg->mod->dev, "Cannot free allocation %p", cb_arg->ptr); + + container_put(cb_arg->mod, container); + + return true; +} + /** * Frees the memory block removes it from module's book keeping. * @param mod Pointer to module this memory block was allocated for. @@ -402,28 +394,19 @@ static int free_contents(struct processing_module *mod, struct module_resource * int z_impl_mod_free(struct processing_module *mod, const void *ptr) { struct module_resources *res = &mod->priv.resources; - struct module_resource *container; - struct list_item *res_list; MEM_API_CHECK_THREAD(res); if (!ptr) return 0; - /* Find which container keeps this memory */ - list_for_item(res_list, &res->res_list) { - container = container_of(res_list, struct module_resource, list); - if (container->ptr == ptr) { - int ret = free_contents(mod, container); - - list_item_del(&container->list); - container_put(mod, container); - return ret; - } - } + /* Find which container holds this memory */ + struct mod_res_cb_arg cb_arg = {mod, ptr}; + int ret = objpool_iterate(&res->objpool, mod_res_free, &cb_arg); - comp_err(mod->dev, "error: could not find memory pointed by %p", ptr); + if (ret < 0) + comp_err(mod->dev, "error: could not find memory pointed by %p", ptr); - return -EINVAL; + return ret; } EXPORT_SYMBOL(z_impl_mod_free); @@ -684,32 +667,14 @@ int module_reset(struct processing_module *mod) void mod_free_all(struct processing_module *mod) { struct module_resources *res = &mod->priv.resources; - struct k_heap *mod_heap = res->heap; - struct list_item *list; - struct list_item *_list; MEM_API_CHECK_THREAD(res); - /* Free all contents found in used containers */ - list_for_item(list, &res->res_list) { - struct module_resource *container = - container_of(list, struct module_resource, list); - - free_contents(mod, container); - } - /* - * We do not need to remove the containers from res_list in - * the loop above or go through free_cont_list as all the - * containers are anyway freed in the loop below, and the list - * heads are reinitialized when mod_resource_init() is called. - */ - list_for_item_safe(list, _list, &res->cont_chunk_list) { - struct container_chunk *chunk = - container_of(list, struct container_chunk, chunk_list); + /* Free all contents found in used containers */ + struct mod_res_cb_arg cb_arg = {mod, NULL}; - list_item_del(&chunk->chunk_list); - sof_heap_free(mod_heap, chunk); - } + objpool_iterate(&res->objpool, mod_res_free, &cb_arg); + objpool_prune(&res->objpool); /* Make sure resource lists and accounting are reset */ mod_resource_init(mod); diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index c60c22becf5c..59f5f398bad5 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -13,8 +13,9 @@ #ifndef __SOF_AUDIO_MODULE_GENERIC__ #define __SOF_AUDIO_MODULE_GENERIC__ -#include +#include #include +#include #include #include #include "module_interface.h" @@ -128,9 +129,7 @@ struct module_param { * when the module unloads. */ struct module_resources { - struct list_item res_list; /**< Allocad resource containers */ - struct list_item free_cont_list; /**< Unused memory containers */ - struct list_item cont_chunk_list; /**< Memory container chunks */ + struct objpool_head objpool; size_t heap_usage; size_t heap_high_water_mark; struct k_heap *heap; diff --git a/src/platform/library/lib/alloc.c b/src/platform/library/lib/alloc.c index d733b58f8541..74cb926e4aff 100644 --- a/src/platform/library/lib/alloc.c +++ b/src/platform/library/lib/alloc.c @@ -70,3 +70,8 @@ void heap_trace_all(int force) { heap_trace(NULL, 0); } + +struct k_heap *sof_sys_heap_get(void) +{ + return NULL; +} diff --git a/test/cmocka/src/audio/eq_fir/CMakeLists.txt b/test/cmocka/src/audio/eq_fir/CMakeLists.txt index 305a6846966c..226128b220d2 100644 --- a/test/cmocka/src/audio/eq_fir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_fir/CMakeLists.txt @@ -37,6 +37,7 @@ add_library(audio_for_eq_fir STATIC ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c + ${PROJECT_SOURCE_DIR}/src/lib/objpool.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/audio/eq_iir/CMakeLists.txt b/test/cmocka/src/audio/eq_iir/CMakeLists.txt index aa704a1af92b..b5ff8770eec2 100644 --- a/test/cmocka/src/audio/eq_iir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_iir/CMakeLists.txt @@ -40,6 +40,7 @@ add_library(audio_for_eq_iir STATIC ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c + ${PROJECT_SOURCE_DIR}/src/lib/objpool.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/audio/mixer/CMakeLists.txt b/test/cmocka/src/audio/mixer/CMakeLists.txt index ea8cad0bd79e..c0dbb8a0a4fc 100644 --- a/test/cmocka/src/audio/mixer/CMakeLists.txt +++ b/test/cmocka/src/audio/mixer/CMakeLists.txt @@ -10,6 +10,7 @@ cmocka_test(mixer ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c + ${PROJECT_SOURCE_DIR}/src/lib/objpool.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c diff --git a/test/cmocka/src/audio/mux/CMakeLists.txt b/test/cmocka/src/audio/mux/CMakeLists.txt index 67b10f77270d..a4a72613fd6b 100644 --- a/test/cmocka/src/audio/mux/CMakeLists.txt +++ b/test/cmocka/src/audio/mux/CMakeLists.txt @@ -25,6 +25,7 @@ add_library( ${PROJECT_SOURCE_DIR}/src/math/numbers.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c + ${PROJECT_SOURCE_DIR}/src/lib/objpool.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter_ipc3.c diff --git a/test/cmocka/src/audio/volume/CMakeLists.txt b/test/cmocka/src/audio/volume/CMakeLists.txt index d89927578222..0385441e5878 100644 --- a/test/cmocka/src/audio/volume/CMakeLists.txt +++ b/test/cmocka/src/audio/volume/CMakeLists.txt @@ -34,6 +34,7 @@ add_library(audio_for_volume STATIC ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c + ${PROJECT_SOURCE_DIR}/src/lib/objpool.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/common_mocks.c b/test/cmocka/src/common_mocks.c index ef996b8f3500..60b6215c4cd5 100644 --- a/test/cmocka/src/common_mocks.c +++ b/test/cmocka/src/common_mocks.c @@ -124,6 +124,11 @@ int WEAK mod_free(struct processing_module *mod, const void *ptr) return 0; } +struct k_heap * WEAK sof_sys_heap_get(void) +{ + return NULL; +} + void WEAK *sof_heap_alloc(struct k_heap *heap, uint32_t flags, size_t bytes, size_t alignment) { diff --git a/zephyr/lib/alloc.c b/zephyr/lib/alloc.c index 8a2fed79ee41..f95f66fbdb7f 100644 --- a/zephyr/lib/alloc.c +++ b/zephyr/lib/alloc.c @@ -9,12 +9,10 @@ #include #include #include -#include #include #include #include #include -#include #include #include #include