diff --git a/posix/include/rtos/alloc.h b/posix/include/rtos/alloc.h index 7927f17394e5..7dbf070259ff 100644 --- a/posix/include/rtos/alloc.h +++ b/posix/include/rtos/alloc.h @@ -61,8 +61,15 @@ * Allocates memory block. * @param flags Flags, see SOF_MEM_FLAG_... * @param bytes Size in bytes. + * @param alignment Alignment in bytes. * @return Pointer to the allocated memory or NULL if failed. */ +void *rmalloc_align(uint32_t flags, size_t bytes, + uint32_t alignment); + +/** + * Similar to rmalloc_align(), but no alignment can be specified. + */ void *rmalloc(uint32_t flags, size_t bytes); /** diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index f95299f952d8..f77377a54cea 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -160,21 +160,25 @@ static void container_put(struct processing_module *mod, struct module_resource } /** - * Allocates aligned memory block for module. + * Allocates aligned buffer 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. + * The allocated memory is automatically freed when the module is + * unloaded. The back-end, rballoc(), always aligns the memory to + * PLATFORM_DCACHE_ALIGN at the minimum. */ -void *mod_alloc_align(struct processing_module *mod, uint32_t size, uint32_t alignment) +void *mod_balloc_align(struct processing_module *mod, size_t size, size_t alignment) { - struct module_resource *container = container_get(mod); struct module_resources *res = &mod->priv.resources; + struct module_resource *container; void *ptr; MEM_API_CHECK_THREAD(res); + + container = container_get(mod); if (!container) return NULL; @@ -184,14 +188,12 @@ void *mod_alloc_align(struct processing_module *mod, uint32_t size, uint32_t ali return NULL; } - /* Allocate memory for module */ - if (alignment) - ptr = rballoc_align(SOF_MEM_FLAG_USER, size, alignment); - else - ptr = rballoc(SOF_MEM_FLAG_USER, size); + /* Allocate buffer memory for module */ + ptr = rballoc_align(SOF_MEM_FLAG_USER, size, alignment); if (!ptr) { - comp_err(mod->dev, "failed to allocate memory."); + comp_err(mod->dev, "Failed to alloc %zu bytes %zu alignment for comp %#x.", + size, alignment, dev_comp_id(mod->dev)); container_put(mod, container); return NULL; } @@ -207,41 +209,57 @@ void *mod_alloc_align(struct processing_module *mod, uint32_t size, uint32_t ali return ptr; } -EXPORT_SYMBOL(mod_alloc_align); +EXPORT_SYMBOL(mod_balloc_align); /** - * Allocates memory block for module. - * @param mod Pointer to module this memory block is allocated for. - * @param bytes Size in bytes. + * 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. * - * Like mod_alloc_align() but the alignment can not be specified. However, - * rballoc() will always aligns the memory to PLATFORM_DCACHE_ALIGN. + * The allocated memory is automatically freed when the module is unloaded. */ -void *mod_alloc(struct processing_module *mod, uint32_t size) +void *mod_alloc_align(struct processing_module *mod, size_t size, size_t alignment) { - return mod_alloc_align(mod, size, 0); -} -EXPORT_SYMBOL(mod_alloc); + struct module_resources *res = &mod->priv.resources; + struct module_resource *container; + 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); + MEM_API_CHECK_THREAD(res); - if (ret) - memset(ret, 0, size); + container = container_get(mod); + if (!container) + return NULL; - return ret; + if (!size) { + comp_err(mod->dev, "requested allocation of 0 bytes."); + container_put(mod, container); + return NULL; + } + + /* Allocate memory for module */ + ptr = rmalloc_align(SOF_MEM_FLAG_USER, size, alignment); + + if (!ptr) { + comp_err(mod->dev, "Failed to alloc %zu bytes %zu alignment for comp %#x.", + size, alignment, dev_comp_id(mod->dev)); + container_put(mod, container); + return NULL; + } + /* Store reference to allocated memory */ + 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) + res->heap_high_water_mark = res->heap_usage; + + return ptr; } -EXPORT_SYMBOL(mod_zalloc); +EXPORT_SYMBOL(mod_alloc_align); /** * Creates a blob handler and releases it when the module is unloaded @@ -255,10 +273,12 @@ struct comp_data_blob_handler * mod_data_blob_handler_new(struct processing_module *mod) { struct module_resources *res = &mod->priv.resources; - struct module_resource *container = container_get(mod); struct comp_data_blob_handler *bhp; + struct module_resource *container; MEM_API_CHECK_THREAD(res); + + container = container_get(mod); if (!container) return NULL; @@ -289,10 +309,12 @@ EXPORT_SYMBOL(mod_data_blob_handler_new); const void *mod_fast_get(struct processing_module *mod, const void * const dram_ptr, size_t size) { struct module_resources *res = &mod->priv.resources; - struct module_resource *container = container_get(mod); + struct module_resource *container; const void *ptr; MEM_API_CHECK_THREAD(res); + + container = container_get(mod); if (!container) return NULL; diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 97e5d9b35520..82430a017204 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -188,9 +188,28 @@ 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_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); +void *mod_balloc_align(struct processing_module *mod, size_t size, size_t alignment); +static inline void *mod_balloc(struct processing_module *mod, size_t size) +{ + return mod_balloc_align(mod, size, 0); +} + +void *mod_alloc_align(struct processing_module *mod, size_t size, size_t alignment); +static inline void *mod_alloc(struct processing_module *mod, size_t size) +{ + return mod_alloc_align(mod, size, 0); +} + +static inline void *mod_zalloc(struct processing_module *mod, size_t size) +{ + void *ret = mod_alloc(mod, size); + + if (ret) + memset(ret, 0, size); + + return ret; +} + int mod_free(struct processing_module *mod, const void *ptr); #if CONFIG_COMP_BLOB struct comp_data_blob_handler *mod_data_blob_handler_new(struct processing_module *mod); diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index 511917ceb768..c35fc41ba364 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -581,7 +581,7 @@ __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) buffer = ipc4_create_buffer(source, cross_core_bind, buf_size, bu->extension.r.src_queue, bu->extension.r.dst_queue); if (!buffer) { - tr_err(&ipc_tr, "failed to allocate buffer to bind %d to %d", src_id, sink_id); + tr_err(&ipc_tr, "failed to allocate buffer to bind %#x to %#x", src_id, sink_id); return IPC4_OUT_OF_MEMORY; } @@ -646,14 +646,14 @@ __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) ret = comp_buffer_connect(source, source->ipc_config.core, buffer, PPL_CONN_DIR_COMP_TO_BUFFER); if (ret < 0) { - tr_err(&ipc_tr, "failed to connect src %d to internal buffer", src_id); + tr_err(&ipc_tr, "failed to connect src %#x to internal buffer", src_id); goto free; } ret = comp_buffer_connect(sink, sink->ipc_config.core, buffer, PPL_CONN_DIR_BUFFER_TO_COMP); if (ret < 0) { - tr_err(&ipc_tr, "failed to connect internal buffer to sink %d", sink_id); + tr_err(&ipc_tr, "failed to connect internal buffer to sink %#x", sink_id); goto e_sink_connect; } @@ -1043,7 +1043,7 @@ __cold const struct comp_driver *ipc4_get_comp_drv(uint32_t module_id) mod = lib_manager_get_module_manifest(module_id); if (!mod) { - tr_err(&comp_tr, "Error: Couldn't find loadable module with id %d.", + tr_err(&comp_tr, "Error: Couldn't find loadable module with id %#x.", module_id); return NULL; } diff --git a/src/platform/library/lib/alloc.c b/src/platform/library/lib/alloc.c index ec7667b351be..1a5b96b68d64 100644 --- a/src/platform/library/lib/alloc.c +++ b/src/platform/library/lib/alloc.c @@ -16,6 +16,11 @@ /* testbench mem alloc definition */ +void *rmalloc_align(uint32_t flags, size_t bytes, uint32_t alignment) +{ + return malloc(bytes); +} + void *rmalloc(uint32_t flags, size_t bytes) { return malloc(bytes); diff --git a/test/cmocka/src/common_mocks.c b/test/cmocka/src/common_mocks.c index cb116c5f8908..1450af20ddfd 100644 --- a/test/cmocka/src/common_mocks.c +++ b/test/cmocka/src/common_mocks.c @@ -63,10 +63,26 @@ void WEAK *rbrealloc_align(void *ptr, uint32_t flags, { (void)flags; (void)old_bytes; + (void)alignment; return realloc(ptr, bytes); } +void WEAK *rmalloc_align(uint32_t flags, size_t bytes, uint32_t alignment) +{ + (void)flags; + (void)alignment; + + return malloc(bytes); +} + +void WEAK *rmalloc(uint32_t flags, size_t bytes) +{ + (void)flags; + + return malloc(bytes); +} + void WEAK rfree(void *ptr) { free(ptr); diff --git a/zephyr/include/rtos/alloc.h b/zephyr/include/rtos/alloc.h index 0cf885ffe2ad..2738a0ac230b 100644 --- a/zephyr/include/rtos/alloc.h +++ b/zephyr/include/rtos/alloc.h @@ -52,9 +52,15 @@ * Allocates memory block. * @param flags Flags, see SOF_MEM_FLAG_.... * @param bytes Size in bytes. + * @param alignment Alignment in bytes. * @return Pointer to the allocated memory or NULL if failed. * */ +void *rmalloc_align(uint32_t flags, size_t bytes, uint32_t alignment); + +/** + * Similar to rmalloc_align(), but no alignment can be specified. + */ void *rmalloc(uint32_t flags, size_t bytes); /** diff --git a/zephyr/lib/alloc.c b/zephyr/lib/alloc.c index 2af0eb83397d..17d8d1a20af5 100644 --- a/zephyr/lib/alloc.c +++ b/zephyr/lib/alloc.c @@ -439,7 +439,7 @@ static void heap_free(struct k_heap *h, void *mem) } -void *rmalloc(uint32_t flags, size_t bytes) +void *rmalloc_align(uint32_t flags, size_t bytes, uint32_t alignment) { void *ptr; struct k_heap *heap; @@ -453,7 +453,7 @@ void *rmalloc(uint32_t flags, size_t bytes) tr_err(&zephyr_tr, "L3_HEAP available for cached addresses only!"); return NULL; } - ptr = (__sparse_force void *)l3_heap_alloc_aligned(heap, 0, bytes); + ptr = (__sparse_force void *)l3_heap_alloc_aligned(heap, alignment, bytes); return ptr; #else @@ -468,17 +468,24 @@ void *rmalloc(uint32_t flags, size_t bytes) } if (!(flags & SOF_MEM_FLAG_COHERENT)) { - ptr = (__sparse_force void *)heap_alloc_aligned_cached(heap, 0, bytes); + ptr = (__sparse_force void *)heap_alloc_aligned_cached(heap, alignment, bytes); } else { /* * XTOS alloc implementation has used dcache alignment, * so SOF application code is expecting this behaviour. */ - ptr = heap_alloc_aligned(heap, PLATFORM_DCACHE_ALIGN, bytes); + alignment = MAX(PLATFORM_DCACHE_ALIGN, alignment); + ptr = heap_alloc_aligned(heap, alignment, bytes); } return ptr; } +EXPORT_SYMBOL(rmalloc_align); + +void *rmalloc(uint32_t flags, size_t bytes) +{ + return rmalloc_align(flags, bytes, 0); +} EXPORT_SYMBOL(rmalloc); void *rbrealloc_align(void *ptr, uint32_t flags, size_t bytes,