diff --git a/src/arch/xtensa/schedule/task.c b/src/arch/xtensa/schedule/task.c index 938bcd99f8e5..148afed6426c 100644 --- a/src/arch/xtensa/schedule/task.c +++ b/src/arch/xtensa/schedule/task.c @@ -83,7 +83,7 @@ int task_context_init(void *task_ctx, void *entry, void *arg0, void *arg1, ctx->stack_size = stack_size; } else { ctx->stack_base = rballoc(RZONE_BUFFER, SOF_MEM_CAPS_RAM, - SOF_TASK_DEFAULT_STACK_SIZE); + SOF_TASK_DEFAULT_STACK_SIZE, false); if (!ctx->stack_base) return -ENOMEM; ctx->stack_size = SOF_TASK_DEFAULT_STACK_SIZE; diff --git a/src/audio/buffer.c b/src/audio/buffer.c index 07711fb6be12..200bf147792f 100644 --- a/src/audio/buffer.c +++ b/src/audio/buffer.c @@ -38,7 +38,7 @@ struct comp_buffer *buffer_alloc(uint32_t size, uint32_t caps, uint32_t align) return NULL; } - buffer->addr = rballoc_align(RZONE_BUFFER, caps, size, align); + buffer->addr = rballoc_align(RZONE_BUFFER, caps, size, align, false); if (!buffer->addr) { rfree(buffer); trace_buffer_error("buffer_alloc() error: " @@ -86,7 +86,8 @@ int buffer_set_size(struct comp_buffer *buffer, uint32_t size) if (size == buffer->size) return 0; - new_ptr = rbrealloc(buffer->addr, RZONE_BUFFER, buffer->caps, size); + new_ptr = rbrealloc(buffer->addr, RZONE_BUFFER, buffer->caps, size, + false); /* we couldn't allocate bigger chunk */ if (!new_ptr && size > buffer->size) { diff --git a/src/audio/detect_test.c b/src/audio/detect_test.c index 6716aa650f58..686bb20c10ad 100644 --- a/src/audio/detect_test.c +++ b/src/audio/detect_test.c @@ -225,7 +225,7 @@ static int alloc_mem_load(struct comp_data *cd, uint32_t size) free_mem_load(cd); - cd->model.data = rballoc(RZONE_BUFFER, SOF_MEM_CAPS_RAM, size); + cd->model.data = rballoc(RZONE_BUFFER, SOF_MEM_CAPS_RAM, size, false); if (!cd->model.data) { trace_keyword_error("alloc_mem_load() alloc failed"); diff --git a/src/audio/eq_fir/eq_fir.c b/src/audio/eq_fir/eq_fir.c index 8adab685384e..6c9d3ef23c60 100644 --- a/src/audio/eq_fir/eq_fir.c +++ b/src/audio/eq_fir/eq_fir.c @@ -345,7 +345,8 @@ static int eq_fir_setup(struct comp_data *cd, int nch) return 0; /* Allocate all FIR channels data in a big chunk and clear it */ - cd->fir_delay = rballoc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, size_sum); + cd->fir_delay = rballoc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, size_sum, + false); if (!cd->fir_delay) { trace_eq_error("eq_fir_setup() error: alloc failed, size = %u", size_sum); @@ -435,7 +436,8 @@ static struct comp_dev *eq_fir_new(struct sof_ipc_comp *comp) * the EQ is configured later in run-time the size is zero. */ if (bs) { - cd->config = rballoc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, bs); + cd->config = rballoc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, bs, + false); if (!cd->config) { rfree(dev); rfree(cd); @@ -609,7 +611,8 @@ static int fir_cmd_set_data(struct comp_dev *dev, /* Allocate buffer for copy of the blob. */ cd->config = rballoc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, cdata->num_elems + - cdata->elems_remaining); + cdata->elems_remaining, + false); if (!cd->config) { trace_eq_error_with_ids(dev, "fir_cmd_set_data() " diff --git a/src/audio/kpb.c b/src/audio/kpb.c index bfda90c827a5..00dcc08af4de 100644 --- a/src/audio/kpb.c +++ b/src/audio/kpb.c @@ -213,7 +213,8 @@ static size_t kpb_allocate_history_buffer(struct comp_data *kpb) /* Try to allocate ca_size (current allocation size). At first * attempt it will be equal to hb_size (history buffer size). */ - new_mem_block = rballoc(RZONE_RUNTIME, hb_mcp[i], ca_size); + new_mem_block = rballoc(RZONE_RUNTIME, hb_mcp[i], ca_size, + true); if (new_mem_block) { /* We managed to allocate a block of ca_size. diff --git a/src/audio/src/src.c b/src/audio/src/src.c index d6de83fbe9b9..4b12d8bf745d 100644 --- a/src/audio/src/src.c +++ b/src/audio/src/src.c @@ -637,7 +637,7 @@ static int src_params(struct comp_dev *dev) rfree(cd->delay_lines); cd->delay_lines = rballoc(RZONE_BUFFER, SOF_MEM_CAPS_RAM, - delay_lines_size); + delay_lines_size, false); if (!cd->delay_lines) { trace_src_error_with_ids(dev, "src_params() error: " "failed to alloc cd->delay_lines, " diff --git a/src/include/sof/lib/alloc.h b/src/include/sof/lib/alloc.h index 715a4c5a3e9a..edb62ce8db2d 100644 --- a/src/include/sof/lib/alloc.h +++ b/src/include/sof/lib/alloc.h @@ -106,10 +106,11 @@ struct mm { /* heap allocation and free */ void *_malloc(int zone, uint32_t caps, size_t bytes); void *_zalloc(int zone, uint32_t caps, size_t bytes); -void *_balloc(int zone, uint32_t caps, size_t bytes, uint32_t alignment); +void *_balloc(int zone, uint32_t caps, size_t bytes, uint32_t alignment, + bool can_fail); void *_realloc(void *ptr, int zone, uint32_t caps, size_t bytes); void *_brealloc(void *ptr, int zone, uint32_t caps, size_t bytes, - uint32_t alignment); + uint32_t alignment, bool can_fail); void rfree(void *ptr); #if CONFIG_DEBUG_HEAP @@ -142,10 +143,11 @@ void rfree(void *ptr); } while (0); \ _ptr; }) -#define rballoc(zone, caps, bytes) \ +#define rballoc(zone, caps, bytes, can_fail) \ ({void *_ptr; \ do { \ - _ptr = _balloc(zone, caps, bytes, PLATFORM_DCACHE_ALIGN);\ + _ptr = _balloc(zone, caps, bytes, PLATFORM_DCACHE_ALIGN, \ + can_fail);\ if (!_ptr) { \ trace_error(TRACE_CLASS_MEM, \ "failed to alloc 0x%x bytes caps 0x%x", \ @@ -168,11 +170,11 @@ void rfree(void *ptr); } while (0); \ _ptr; }) -#define rbrealloc(ptr, zone, caps, bytes) \ +#define rbrealloc(ptr, zone, caps, bytes, can_fail) \ ({void *_ptr; \ do { \ _ptr = _brealloc(ptr, zone, caps, bytes,\ - PLATFORM_DCACHE_ALIGN);\ + PLATFORM_DCACHE_ALIGN, can_fail);\ if (!_ptr) { \ trace_error(TRACE_CLASS_MEM, \ "failed to alloc 0x%x bytes caps 0x%x", \ @@ -182,10 +184,11 @@ void rfree(void *ptr); } while (0); \ _ptr; }) -#define rbrealloc_align(ptr, zone, caps, bytes, alignment) \ +#define rbrealloc_align(ptr, zone, caps, bytes, alignment, can_fail) \ ({void *_ptr; \ do { \ - _ptr = _brealloc(ptr, zone, caps, bytes, alignment); \ + _ptr = _brealloc(ptr, zone, caps, bytes, alignment, \ + can_fail); \ if (!_ptr) { \ trace_error(TRACE_CLASS_MEM, \ "failed to alloc 0x%x bytes caps 0x%x", \ @@ -195,10 +198,10 @@ void rfree(void *ptr); } while (0); \ _ptr; }) -#define rballoc_align(zone, caps, bytes, alignment) \ +#define rballoc_align(zone, caps, bytes, alignment, can_fail) \ ({void *_ptr; \ do { \ - _ptr = _balloc(zone, caps, bytes, alignment); \ + _ptr = _balloc(zone, caps, bytes, alignment, can_fail); \ if (!_ptr) { \ trace_error(TRACE_CLASS_MEM, \ "failed to alloc 0x%x bytes caps 0x%x", \ @@ -215,16 +218,16 @@ void alloc_trace_buffer_heap(int zone, uint32_t caps, size_t bytes); #define rmalloc(zone, caps, bytes) _malloc(zone, caps, bytes) #define rzalloc(zone, caps, bytes) _zalloc(zone, caps, bytes) -#define rballoc(zone, caps, bytes) \ - _balloc(zone, caps, bytes, PLATFORM_DCACHE_ALIGN) -#define rballoc_align(zone, caps, bytes, alignment) \ - _balloc(zone, caps, bytes, alignment) +#define rballoc(zone, caps, bytes, can_fail) \ + _balloc(zone, caps, bytes, PLATFORM_DCACHE_ALIGN, can_fail) +#define rballoc_align(zone, caps, bytes, alignment, can_fail) \ + _balloc(zone, caps, bytes, alignment, can_fail) #define rrealloc(ptr, zone, caps, bytes) \ _realloc(ptr, zone, caps, bytes) -#define rbrealloc(ptr, zone, caps, bytes) \ - _brealloc(ptr, zone, caps, bytes, PLATFORM_DCACHE_ALIGN) -#define rbrealloc_align(ptr, zone, caps, bytes, alignment) \ - _brealloc(ptr, zone, caps, bytes, alignment) +#define rbrealloc(ptr, zone, caps, bytes, can_fail) \ + _brealloc(ptr, zone, caps, bytes, PLATFORM_DCACHE_ALIGN, can_fail) +#define rbrealloc_align(ptr, zone, caps, bytes, alignment, can_fail) \ + _brealloc(ptr, zone, caps, bytes, alignment, can_fail) #endif diff --git a/src/lib/alloc.c b/src/lib/alloc.c index 11c391516637..4ccb73b191ed 100644 --- a/src/lib/alloc.c +++ b/src/lib/alloc.c @@ -263,7 +263,7 @@ static void *alloc_block(struct mm_heap *heap, int level, /* allocates continuous blocks */ static void *alloc_cont_blocks(struct mm_heap *heap, int level, - uint32_t caps, size_t bytes, uint32_t alignment) + uint32_t caps, size_t bytes, uint32_t alignment, bool can_fail) { struct block_map *map = &heap->map[level]; struct block_hdr *hdr; @@ -292,9 +292,16 @@ static void *alloc_cont_blocks(struct mm_heap *heap, int level, } if (count > map->count || remaining < count) { - trace_mem_error("error: %d blocks needed for allocation " - "but only %d blocks are remaining", - count, remaining); + if (can_fail) + trace_mem_error("Error: %d blocks needed for " + "allocation of %d bytes but only %d " + "blocks are remaining", count, bytes, + remaining); + else + trace_mem_init("Warning! Not enough free blocks to " + "satisfy request of %d bytes. " + "Available blocks %d, needed %d", + bytes, count, remaining); return NULL; } @@ -717,7 +724,7 @@ void *rzalloc_core_sys(int core, size_t bytes) /* allocates continuous buffers - not for direct use, clients use rballoc() */ static void *alloc_heap_buffer(struct mm_heap *heap, int zone, uint32_t caps, - size_t bytes, uint32_t alignment) + size_t bytes, uint32_t alignment, bool can_fail) { struct block_map *map; int i, temp_bytes = bytes; @@ -770,7 +777,8 @@ static void *alloc_heap_buffer(struct mm_heap *heap, int zone, uint32_t caps, /* allocate if block size is smaller than request */ if (heap->size >= bytes && map->block_size < bytes) { ptr = alloc_cont_blocks(heap, i, caps, - bytes, alignment); + bytes, alignment, + can_fail); if (ptr) break; } @@ -789,7 +797,7 @@ static void *alloc_heap_buffer(struct mm_heap *heap, int zone, uint32_t caps, } static void *_balloc_unlocked(int zone, uint32_t caps, size_t bytes, - uint32_t alignment) + uint32_t alignment, bool can_fail) { struct mm_heap *heap; unsigned int i, n; @@ -803,7 +811,8 @@ static void *_balloc_unlocked(int zone, uint32_t caps, size_t bytes, if (!heap) break; - ptr = alloc_heap_buffer(heap, zone, caps, bytes, alignment); + ptr = alloc_heap_buffer(heap, zone, caps, bytes, alignment, + can_fail); if (ptr) break; @@ -814,14 +823,15 @@ static void *_balloc_unlocked(int zone, uint32_t caps, size_t bytes, } /* allocates continuous buffers - not for direct use, clients use rballoc() */ -void *_balloc(int zone, uint32_t caps, size_t bytes, uint32_t alignment) +void *_balloc(int zone, uint32_t caps, size_t bytes, uint32_t alignment, + bool can_fail) { void *ptr = NULL; uint32_t flags; spin_lock_irq(memmap.lock, flags); - ptr = _balloc_unlocked(zone, caps, bytes, alignment); + ptr = _balloc_unlocked(zone, caps, bytes, alignment, can_fail); spin_unlock_irq(memmap.lock, flags); @@ -891,7 +901,7 @@ void *_realloc(void *ptr, int zone, uint32_t caps, size_t bytes) } void *_brealloc(void *ptr, int zone, uint32_t caps, size_t bytes, - uint32_t alignment) + uint32_t alignment, bool can_fail) { void *new_ptr = NULL; uint32_t flags; @@ -901,7 +911,7 @@ void *_brealloc(void *ptr, int zone, uint32_t caps, size_t bytes, spin_lock_irq(memmap.lock, flags); - new_ptr = _balloc_unlocked(zone, caps, bytes, alignment); + new_ptr = _balloc_unlocked(zone, caps, bytes, alignment, can_fail); if (new_ptr && ptr) memcpy_s(new_ptr, bytes, ptr, bytes); diff --git a/src/trace/dma-trace.c b/src/trace/dma-trace.c index cfaaf495788b..16abe67e8385 100644 --- a/src/trace/dma-trace.c +++ b/src/trace/dma-trace.c @@ -165,7 +165,7 @@ static int dma_trace_buffer_init(struct dma_trace_data *d) /* allocate new buffer */ buf = rballoc(RZONE_BUFFER, SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA, - DMA_TRACE_LOCAL_SIZE); + DMA_TRACE_LOCAL_SIZE, false); if (!buf) { trace_buffer_error("dma_trace_buffer_init() error: " "alloc failed");