From 410ebe4e34e1608444fb920bad2e752cc2e74d49 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Mon, 26 Jul 2021 19:07:39 +0800 Subject: [PATCH 1/2] alloc: trace error when allocation failed with no condition No matter if CONFIG_DEBUG_HEAP selected or not, we need to print out error message when allocation failed. Furthermore, dump the whold heap usage in case under heap debugging or allocation failure. Signed-off-by: Keyon Jie --- src/lib/alloc.c | 207 ++++++++++++++---------------------------------- 1 file changed, 61 insertions(+), 146 deletions(-) diff --git a/src/lib/alloc.c b/src/lib/alloc.c index ce340a1b471d..8ea9e1db1307 100644 --- a/src/lib/alloc.c +++ b/src/lib/alloc.c @@ -548,113 +548,88 @@ static void free_block(void *ptr) #endif } -#if CONFIG_DEBUG_HEAP - -static void trace_heap_blocks(struct mm_heap *heap) +#if CONFIG_TRACE +void heap_trace(struct mm_heap *heap, int size) { - struct block_map *block_map; + struct block_map *current_map; int i; + int j; - tr_err(&mem_tr, "heap: 0x%x size %d blocks %d caps 0x%x", heap->heap, - heap->size, heap->blocks, heap->caps); - tr_err(&mem_tr, " used %d free %d", heap->info.used, - heap->info.free); + for (i = 0; i < size; i++) { + tr_info(&mem_tr, " heap: 0x%x size %d blocks %d caps 0x%x", + heap->heap, heap->size, heap->blocks, + heap->caps); + tr_info(&mem_tr, " used %d free %d", heap->info.used, + heap->info.free); - for (i = 0; i < heap->blocks; i++) { - block_map = &heap->map[i]; + /* map[j]'s base is calculated based on map[j-1] */ + for (j = 0; j < heap->blocks; j++) { + current_map = &heap->map[j]; - tr_err(&mem_tr, " block %d base 0x%x size %d count %d", i, - block_map->base, block_map->block_size, - block_map->count); - tr_err(&mem_tr, " free %d first at %d", - block_map->free_count, block_map->first_free); + tr_info(&mem_tr, " block %d base 0x%x size %d", + j, current_map->base, + current_map->block_size); + tr_info(&mem_tr, " count %d free %d", + current_map->count, + current_map->free_count); + } + heap++; } - } -static void alloc_trace_heap(enum mem_zone zone, uint32_t caps, size_t bytes) +void heap_trace_all(int force) { struct mm *memmap = memmap_get(); - struct mm_heap *heap_base; - struct mm_heap *heap; - unsigned int heap_count; - unsigned int n; - unsigned int i = 0; - int count = 0; - switch (zone) { - case SOF_MEM_ZONE_SYS: - heap_base = memmap->system; - heap_count = PLATFORM_HEAP_SYSTEM; - break; - case SOF_MEM_ZONE_SYS_RUNTIME: - heap_base = memmap->system_runtime; - heap_count = PLATFORM_HEAP_SYSTEM_RUNTIME; - break; - case SOF_MEM_ZONE_RUNTIME: - heap_base = memmap->runtime; - heap_count = PLATFORM_HEAP_RUNTIME; - break; - case SOF_MEM_ZONE_BUFFER: - heap_base = memmap->buffer; - heap_count = PLATFORM_HEAP_BUFFER; - break; + /* has heap changed since last shown */ + if (memmap->heap_trace_updated || force) { + tr_info(&mem_tr, "heap: system status"); + heap_trace(memmap->system, PLATFORM_HEAP_SYSTEM); + tr_info(&mem_tr, "heap: system runtime status"); + heap_trace(memmap->system_runtime, PLATFORM_HEAP_SYSTEM_RUNTIME); + tr_info(&mem_tr, "heap: buffer status"); + heap_trace(memmap->buffer, PLATFORM_HEAP_BUFFER); + tr_info(&mem_tr, "heap: runtime status"); + heap_trace(memmap->runtime, PLATFORM_HEAP_RUNTIME); #if CONFIG_CORE_COUNT > 1 - case SOF_MEM_ZONE_RUNTIME_SHARED: - heap_base = memmap->runtime_shared; - heap_count = PLATFORM_HEAP_RUNTIME_SHARED; - break; - case SOF_MEM_ZONE_SYS_SHARED: - heap_base = memmap->system_shared; - heap_count = PLATFORM_HEAP_SYSTEM_SHARED; - break; -#else - case SOF_MEM_ZONE_RUNTIME_SHARED: - heap_base = memmap->runtime; - heap_count = PLATFORM_HEAP_RUNTIME; - break; - case SOF_MEM_ZONE_SYS_SHARED: - heap_base = memmap->system; - heap_count = PLATFORM_HEAP_SYSTEM; - break; + tr_info(&mem_tr, "heap: runtime shared status"); + heap_trace(memmap->runtime_shared, PLATFORM_HEAP_RUNTIME_SHARED); + tr_info(&mem_tr, "heap: system shared status"); + heap_trace(memmap->system_shared, PLATFORM_HEAP_SYSTEM_SHARED); #endif - default: - tr_err(&mem_tr, "alloc trace: unsupported mem zone"); - goto out; } - heap = heap_base; - n = heap_count; - - while (i < heap_count) { - heap = get_heap_from_caps(heap, n, caps); - if (!heap) - break; - trace_heap_blocks(heap); - count++; - i = heap - heap_base + 1; - n = heap_count - i; - heap++; - } + memmap->heap_trace_updated = 0; - if (count == 0) - tr_err(&mem_tr, "heap: none found for zone %d caps 0x%x, bytes 0x%x", - zone, caps, bytes); -out: - return; } +#else +void heap_trace_all(int force) { } +void heap_trace(struct mm_heap *heap, int size) { } +#endif -#define DEBUG_TRACE_PTR(ptr, bytes, zone, caps, flags) \ - if (trace_get()) { \ - if (!ptr) { \ - tr_err(&mem_tr, "failed to alloc 0x%x bytes zone 0x%x caps 0x%x flags 0x%x", \ - bytes, zone, caps, flags); \ - alloc_trace_heap(zone, caps, bytes); \ - } +#define _ALLOC_FAILURE(bytes, zone, caps, flags) \ + tr_err(&mem_tr, \ + "failed to alloc 0x%x bytes zone 0x%x caps 0x%x flags 0x%x", \ + bytes, zone, caps, flags) +#if CONFIG_DEBUG_HEAP +#define DEBUG_TRACE_PTR(ptr, bytes, zone, caps, flags) do { \ + if (trace_get()) { \ + if (!(ptr)) \ + _ALLOC_FAILURE(bytes, zone, caps, flags); \ + heap_trace_all(0); \ + } \ + } while (0) #else -#define DEBUG_TRACE_PTR(ptr, bytes, zone, caps, flags) +#define DEBUG_TRACE_PTR(ptr, bytes, zone, caps, flags) do { \ + if (trace_get()) { \ + if (!(ptr)) { \ + _ALLOC_FAILURE(bytes, zone, caps, flags); \ + heap_trace_all(0); \ + } \ + } \ + } while (0) #endif /* allocate single block for system runtime */ @@ -1084,66 +1059,6 @@ void free_heap(enum mem_zone zone) } -#if CONFIG_TRACE -void heap_trace(struct mm_heap *heap, int size) -{ - struct block_map *current_map; - int i; - int j; - - for (i = 0; i < size; i++) { - tr_info(&mem_tr, " heap: 0x%x size %d blocks %d caps 0x%x", - heap->heap, heap->size, heap->blocks, - heap->caps); - tr_info(&mem_tr, " used %d free %d", heap->info.used, - heap->info.free); - - /* map[j]'s base is calculated based on map[j-1] */ - for (j = 0; j < heap->blocks; j++) { - current_map = &heap->map[j]; - - tr_info(&mem_tr, " block %d base 0x%x size %d", - j, current_map->base, - current_map->block_size); - tr_info(&mem_tr, " count %d free %d", - current_map->count, - current_map->free_count); - } - - heap++; - } -} - -void heap_trace_all(int force) -{ - struct mm *memmap = memmap_get(); - - /* has heap changed since last shown */ - if (memmap->heap_trace_updated || force) { - tr_info(&mem_tr, "heap: system status"); - heap_trace(memmap->system, PLATFORM_HEAP_SYSTEM); - tr_info(&mem_tr, "heap: system runtime status"); - heap_trace(memmap->system_runtime, PLATFORM_HEAP_SYSTEM_RUNTIME); - tr_info(&mem_tr, "heap: buffer status"); - heap_trace(memmap->buffer, PLATFORM_HEAP_BUFFER); - tr_info(&mem_tr, "heap: runtime status"); - heap_trace(memmap->runtime, PLATFORM_HEAP_RUNTIME); -#if CONFIG_CORE_COUNT > 1 - tr_info(&mem_tr, "heap: runtime shared status"); - heap_trace(memmap->runtime_shared, PLATFORM_HEAP_RUNTIME_SHARED); - tr_info(&mem_tr, "heap: system shared status"); - heap_trace(memmap->system_shared, PLATFORM_HEAP_SYSTEM_SHARED); -#endif - } - - memmap->heap_trace_updated = 0; - -} -#else -void heap_trace_all(int force) { } -void heap_trace(struct mm_heap *heap, int size) { } -#endif - /* initialise map */ void init_heap(struct sof *sof) { From 47606c28906aafe53b34ace1bb5db47a5c3acdc6 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Mon, 26 Jul 2021 19:04:26 +0800 Subject: [PATCH 2/2] trace: Kconfig: disable filtering by default The trace filtering will suppress useful logs and make debugging difficult, disable it by default. Signed-off-by: Keyon Jie --- src/trace/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/trace/Kconfig b/src/trace/Kconfig index 2e7cdfc2f1e6..f26aabf5cc73 100644 --- a/src/trace/Kconfig +++ b/src/trace/Kconfig @@ -35,14 +35,14 @@ config TRACEM config TRACE_FILTERING bool "Trace filtering" depends on TRACE - default y + default n help Filtering of trace messages based on their verbosity level and frequency. config TRACE_FILTERING_VERBOSITY bool "Filter by verbosity" depends on TRACE_FILTERING - default y + default n help Filtering by log verbosity level, where maximum verbosity allowed is specified for each context and may be adjusted in runtime. @@ -50,7 +50,7 @@ config TRACE_FILTERING_VERBOSITY config TRACE_FILTERING_ADAPTIVE bool "Adaptive rate limiting" depends on TRACE_FILTERING - default y + default n help Adaptive filtering of trace messages, tracking up to CONFIG_TRACE_RECENT_ENTRIES_COUNT, suppressing all repeated messages for up to CONFIG_TRACE_RECENT_TIME_THRESHOLD cycles.