From 43ab51b3b51c5ac6f1dc6ec68b18cf338873c944 Mon Sep 17 00:00:00 2001 From: Marcin Rajwa Date: Tue, 5 Nov 2019 19:00:08 +0100 Subject: [PATCH] alloc: don't log error if failure was allowed This patch adds another argument to allocator functions which defines if allocation must succeed or can fail. Such addition is needed as in some cases components "probe" memory caps if they ara capable of storing certain amount of data. If they ain't, nothing wrong happens in functional regards since components either decrease is original request or use different memory region. However with current implementation you will see error message saying that allocation has failed. This is very misleading if success of allocation wasn't necessary. Signed-off-by: Marcin Rajwa --- src/arch/xtensa/schedule/task.c | 2 +- src/audio/buffer.c | 5 +++-- src/audio/detect_test.c | 2 +- src/audio/eq_fir/eq_fir.c | 9 +++++--- src/audio/kpb.c | 3 ++- src/audio/src/src.c | 2 +- src/include/sof/lib/alloc.h | 39 ++++++++++++++++++--------------- src/lib/alloc.c | 34 ++++++++++++++++++---------- src/trace/dma-trace.c | 2 +- 9 files changed, 58 insertions(+), 40 deletions(-) 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");