diff --git a/zephyr/include/sof/lib/regions_mm.h b/zephyr/include/sof/lib/regions_mm.h index 757094e32fcf..9e960e304b65 100644 --- a/zephyr/include/sof/lib/regions_mm.h +++ b/zephyr/include/sof/lib/regions_mm.h @@ -87,6 +87,9 @@ int vmh_free_heap(struct vmh_heap *heap); int vmh_free(struct vmh_heap *heap, void *ptr); void vmh_get_default_heap_config(const struct sys_mm_drv_region *region, struct vmh_heap_config *cfg); +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS +void vmh_log_stats(struct vmh_heap *heap); +#endif /** * @brief Checks if ptr is in range of given memory range * diff --git a/zephyr/lib/alloc.c b/zephyr/lib/alloc.c index 946a07b9124a..2c5754f92b27 100644 --- a/zephyr/lib/alloc.c +++ b/zephyr/lib/alloc.c @@ -292,8 +292,12 @@ static void *virtual_heap_alloc(struct vmh_heap *heap, uint32_t flags, size_t by { void *mem = vmh_alloc(heap, bytes); - if (!mem) + if (!mem) { +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS + vmh_log_stats(heap); +#endif return NULL; + } assert(align == 0 || IS_ALIGNED(mem, align)); diff --git a/zephyr/lib/regions_mm.c b/zephyr/lib/regions_mm.c index c9b307b8f298..9b8db4b504af 100644 --- a/zephyr/lib/regions_mm.c +++ b/zephyr/lib/regions_mm.c @@ -10,6 +10,7 @@ #if defined(CONFIG_MM_DRV) #include +LOG_MODULE_DECLARE(mem_allocator, CONFIG_SOF_LOG_LEVEL); /** @struct vmh_heap * @@ -32,6 +33,10 @@ struct vmh_heap { const struct sys_mm_drv_region *virtual_region; struct sys_mem_blocks *physical_blocks_allocators[MAX_MEMORY_ALLOCATORS_COUNT]; struct sys_bitarray *allocation_sizes[MAX_MEMORY_ALLOCATORS_COUNT]; +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS + unsigned int out_of_blocks[MAX_MEMORY_ALLOCATORS_COUNT]; + bool logged; +#endif bool allocating_continuously; }; @@ -398,6 +403,9 @@ static void *_vmh_alloc(struct vmh_heap *heap, uint32_t alloc_size) int mem_block_iterator, allocation_error_code = -ENOMEM; size_t allocation_bitarray_offset, block_count = 0, block_size = 0, allocation_bitarray_position = 0; +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS + bool first_match = true; +#endif /* We will gather error code when allocating on physical block * allocators. @@ -487,6 +495,11 @@ static void *_vmh_alloc(struct vmh_heap *heap, uint32_t alloc_size) sys_bitarray_set_region(heap->allocation_sizes[mem_block_iterator], block_count - 1, allocation_bitarray_position); break; +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS + } else if (first_match) { + ++heap->out_of_blocks[mem_block_iterator]; + first_match = false; +#endif } } @@ -699,6 +712,39 @@ int vmh_free(struct vmh_heap *heap, void *ptr) return ret; } +#ifdef CONFIG_SYS_MEM_BLOCKS_RUNTIME_STATS +/** + * @brief Print stats on heap usage per allocator + * + * @param heap pointer to a heap for which statistics are collected + */ +void vmh_log_stats(struct vmh_heap *heap) +{ + if (heap->logged) + return; + + LOG_INF("Virtual heap stats per allocator"); + LOG_INF(" ID | Total | Max use| Times run out of blocks"); + + for (int idx = 0; idx < MAX_MEMORY_ALLOCATORS_COUNT; idx++) { + if (!heap->physical_blocks_allocators[idx]) + continue; + + struct sys_memory_stats stats = {0}; + + sys_mem_blocks_runtime_stats_get(heap->physical_blocks_allocators[idx], &stats); + + size_t block_size = 1 << heap->physical_blocks_allocators[idx]->info.blk_sz_shift; + size_t block_num = heap->physical_blocks_allocators[idx]->info.num_blocks; + + LOG_INF("%7d| %7u| %7u| %7u", idx, block_num, + (stats.max_allocated_bytes / block_size), + heap->out_of_blocks[idx]); + } + heap->logged = true; +} +#endif + /** * @brief Get default configuration for heap *