From 5d4955fd74bbd843703d0ec0d9a2cfce9b0321dd Mon Sep 17 00:00:00 2001 From: Paul Olaru Date: Fri, 20 Dec 2019 16:27:46 +0200 Subject: [PATCH] alloc: Fix bug in handling first_free member of the block map That field is intended to point to the first free block of this particular block map (part of heap). As long as the heap doesn't fill up the old code manages it correctly. However once the block map becomes full (all blocks are occupied) this member will no longer point to a free block. Without this fix rfree may fail to update this pointer to point to the correct block when freeing a block from a full heap. Not updating this will cause subsequent memory allocations to hand out used blocks as if they were free. This fix ensures that will not happen in this edge case. Signed-off-by: Paul Olaru --- src/lib/alloc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/alloc.c b/src/lib/alloc.c index eea1cef4be92..78acd12e9366 100644 --- a/src/lib/alloc.c +++ b/src/lib/alloc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -447,6 +448,7 @@ static void free_block(void *ptr) int i; int block; int used_blocks; + bool heap_is_full; heap = get_heap_from_ptr(ptr); if (!heap) { @@ -499,6 +501,8 @@ static void free_block(void *ptr) if (block_map->base + block_map->block_size * block != (uint32_t)ptr) panic(SOF_IPC_PANIC_MEM); + heap_is_full = !block_map->free_count; + /* free block header and continuous blocks */ used_blocks = block + hdr->size; @@ -513,7 +517,7 @@ static void free_block(void *ptr) } /* set first free block */ - if (block < block_map->first_free) + if (block < block_map->first_free || heap_is_full) block_map->first_free = block; writeback_block_map(block_map);