From ad24132888d2bf9b92f8de8c274715c87f7115a3 Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Thu, 8 May 2025 15:02:05 +0200 Subject: [PATCH 1/3] audio: component: Pass error code in comp_trigger_local Update comp_trigger_local to return the error code returned by the schedule_task function. Signed-off-by: Adrian Warecki --- src/include/sof/audio/component_ext.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/include/sof/audio/component_ext.h b/src/include/sof/audio/component_ext.h index 0fac007cfe36..55b8dc9e4f40 100644 --- a/src/include/sof/audio/component_ext.h +++ b/src/include/sof/audio/component_ext.h @@ -152,6 +152,8 @@ static inline int comp_trigger_local(struct comp_dev *dev, int cmd) int ret; ret = dev->drv->ops.trigger(dev, cmd); + if (ret) + return ret; /* start a thread in case of shared component or DP scheduling */ if (dev->task) { @@ -159,7 +161,7 @@ static inline int comp_trigger_local(struct comp_dev *dev, int cmd) switch (cmd) { case COMP_TRIGGER_START: case COMP_TRIGGER_RELEASE: - schedule_task(dev->task, 0, dev->period); + ret = schedule_task(dev->task, 0, dev->period); break; case COMP_TRIGGER_XRUN: case COMP_TRIGGER_PAUSE: From d697bc28959d01b8306d8ed967631c20a02d622a Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Wed, 26 Nov 2025 17:02:58 +0100 Subject: [PATCH 2/3] ipc4: helper: Fix error handling in ipc_comp_connect Handle ring buffer allocation failure by jumping to the new free_unlocked label that skips ll_unblock. Do not release the lock at this point because it is acquired later. Signed-off-by: Adrian Warecki --- src/ipc/ipc4/helper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index 3aee3b69313f..700aa96944f6 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -613,7 +613,7 @@ __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) audio_buffer_is_shared(&buffer->audio_buffer), buf_get_id(buffer)); if (!ring_buffer) - goto free; + goto free_unlocked; /* data destination module needs to use ring_buffer */ audio_buffer_attach_secondary_buffer(&buffer->audio_buffer, dp_on_source, @@ -698,6 +698,7 @@ __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) pipeline_disconnect(source, buffer, PPL_CONN_DIR_COMP_TO_BUFFER); free: ll_unblock(cross_core_bind, flags); +free_unlocked: buffer_free(buffer); return IPC4_INVALID_RESOURCE_STATE; } From f915ec35a057a04fd7b59e642ba223dfa9bbb17e Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Wed, 26 Nov 2025 17:51:18 +0100 Subject: [PATCH 3/3] alloc: sof_heap: Add missing support for shared buffers in sof_heap_alloc Add missing support for the SOF_MEM_FLAG_USER_SHARED_BUFFER flag in the sof_heap_alloc function. Add a generic function is_heap_pointer that allows checking whether a given pointer belongs to a given heap. It is used in the sof_heap_free function to ensure that the freed pointer belongs to the specified heap, and if not, to free it using rfree. Signed-off-by: Adrian Warecki --- src/audio/module_adapter/module_adapter.c | 2 ++ zephyr/lib/alloc.c | 23 +++++++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index c64a650e0b38..fdcc5d3c3af9 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -70,6 +70,8 @@ static struct k_heap *module_adapter_dp_heap_new(const struct comp_ipc_config *c void *mod_heap_buf = mod_heap_mem + heap_prefix_size; k_heap_init(mod_heap, mod_heap_buf, heap_size - heap_prefix_size); + mod_heap->heap.init_mem = mod_heap_buf; + mod_heap->heap.init_bytes = heap_size - heap_prefix_size; return mod_heap; } diff --git a/zephyr/lib/alloc.c b/zephyr/lib/alloc.c index c93ffcd80dab..55be90d8208c 100644 --- a/zephyr/lib/alloc.c +++ b/zephyr/lib/alloc.c @@ -155,6 +155,25 @@ extern char _end[], _heap_sentry[]; static struct k_heap sof_heap; +/** + * Checks whether pointer is from a given heap memory. + * @param heap Pointer to a heap. + * @param ptr Pointer to memory being checked. + * @return True if pointer falls into heap memory region, false otherwise. + */ +static bool is_heap_pointer(const struct k_heap *heap, void *ptr) +{ + uintptr_t heap_start = + POINTER_TO_UINT(sys_cache_cached_ptr_get(heap->heap.init_mem)); + uintptr_t heap_end = heap_start + heap->heap.init_bytes; + + if (!is_cached(ptr)) + ptr = (__sparse_force void *)sys_cache_cached_ptr_get(ptr); + + return ((POINTER_TO_UINT(ptr) >= heap_start) && + (POINTER_TO_UINT(ptr) < heap_end)); +} + #if CONFIG_SOF_USERSPACE_USE_SHARED_HEAP static struct k_heap shared_buffer_heap; @@ -628,7 +647,7 @@ EXPORT_SYMBOL(rfree); void *sof_heap_alloc(struct k_heap *heap, uint32_t flags, size_t bytes, size_t alignment) { - if (flags & SOF_MEM_FLAG_LARGE_BUFFER) + if (flags & (SOF_MEM_FLAG_LARGE_BUFFER | SOF_MEM_FLAG_USER_SHARED_BUFFER)) return rballoc_align(flags, bytes, alignment); if (!heap) @@ -642,7 +661,7 @@ void *sof_heap_alloc(struct k_heap *heap, uint32_t flags, size_t bytes, void sof_heap_free(struct k_heap *heap, void *addr) { - if (heap && addr) + if (heap && addr && is_heap_pointer(heap, addr)) heap_free(heap, addr); else rfree(addr);