memory: fix extensive, continuous memory blocks allocation

This commit fixes a problem with memory allocation of big
areas of memory dedicated i.e for buffers. The calculation of
remainnig blocks of memory was incorect and disallowed usage
of available blocks.

Signed-off-by: Marcin Rajwa <marcin.rajwa@linux.intel.com>
This commit is contained in:
Marcin Rajwa 2019-03-08 00:58:26 +01:00 committed by Liam Girdwood
parent 2dbe69e294
commit f61fcc1243
2 changed files with 19 additions and 43 deletions

View File

@ -94,7 +94,8 @@ struct block_map {
} __attribute__ ((__aligned__(PLATFORM_DCACHE_ALIGN)));
#define BLOCK_DEF(sz, cnt, hdr) \
{.block_size = sz, .count = cnt, .free_count = cnt, .block = hdr}
{.block_size = sz, .count = cnt, .free_count = cnt, .block = hdr, \
.first_free = 0}
struct mm_heap {
uint32_t blocks;

View File

@ -250,70 +250,45 @@ static void *alloc_cont_blocks(struct mm_heap *heap, int level,
unsigned int start;
unsigned int current;
unsigned int count = bytes / map->block_size;
unsigned int i;
unsigned int remaining = map->count - count;
unsigned int end;
unsigned int remaining = 0;
if (bytes % map->block_size)
count++;
/* check for continuous blocks from "start" */
for (start = map->first_free; start < remaining; start++) {
/* check that we have enough free blocks from start pos */
end = start + count;
for (current = start; current < end; current++) {
/* check if we have enough consecutive blocks for requested
* allocation size.
*/
for (current = map->first_free; current < map->count ||
count > remaining; current++) {
hdr = &map->block[current];
/* is block used */
if (hdr->used) {
/* continue after the "current" */
start = current;
break;
}
if (!hdr->used)
remaining++;
}
/* enough free blocks ? */
if (current == end)
break;
}
if (start >= remaining) {
/* not found */
trace_mem_error("error: cant find %d cont blocks %d remaining",
if (count > map->count || remaining < count) {
trace_mem_error("error: %d blocks needed for allocation "
"but only %d blocks are remaining",
count, remaining);
return NULL;
}
/* found some free blocks */
/* we found enough space, let's allocate it */
start = map->first_free;
map->free_count -= count;
ptr = (void *)(map->base + start * map->block_size);
hdr = &map->block[start];
hdr->size = count;
heap->info.used += count * map->block_size;
heap->info.free -= count * map->block_size;
map->first_free = map->first_free + count;
/* allocate each block */
for (current = start; current < end; current++) {
/* update each block */
for (current = start; current < count; current++) {
hdr = &map->block[current];
hdr->used = 1;
}
/* do we need to find a new first free block ? */
if (start == map->first_free) {
/* find next free */
for (i = map->first_free + count; i < map->count; ++i) {
hdr = &map->block[i];
if (hdr->used == 0) {
map->first_free = i;
break;
}
}
}
return ptr;
}