[Sound-open-firmware] [PATCH] alloc: Add support for allocating different types of memory from the heap

Keyon Jie yang.jie at linux.intel.com
Fri Sep 1 10:41:25 CEST 2017


To add support for different types of heap memory, here it will:

1. add handle for RFLAGS_DMA which will allocate DMA buffer blocks
if exist;
2. refine free_block, which will free blocks of runtime heap,
general buffer heap, or dma buffer heap.

Signed-off-by: Keyon Jie <yang.jie at linux.intel.com>
Tested-by: Zhang Keqiao <keqiao.zhang at intel.com>
---
 src/lib/alloc.c | 82 +++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 56 insertions(+), 26 deletions(-)

diff --git a/src/lib/alloc.c b/src/lib/alloc.c
index 86c2bc7..e28817b 100644
--- a/src/lib/alloc.c
+++ b/src/lib/alloc.c
@@ -334,20 +334,38 @@ found:
 /* free block(s) */
 static void free_block(struct mm_heap *heap, void *ptr)
 {
-	struct block_map *map;
+	struct mm_heap * mm_heap;
+	struct block_map * block_map;
 	struct block_hdr *hdr;
-	int i, block;
+	int i, block, array_size;
 
 	/* sanity check */
 	if (ptr == NULL)
 		return;
 
+	/* find mm_heap that ptr belongs to */
+	if ((uint32_t)ptr >= memmap.runtime.heap &&
+		(uint32_t)ptr < memmap.runtime.heap + memmap.runtime.size) {
+		mm_heap = &memmap.runtime;
+		array_size = ARRAY_SIZE(rt_heap_map);
+	} else if ((uint32_t)ptr >= memmap.buffer.heap &&
+		(uint32_t)ptr < memmap.buffer.heap + memmap.buffer.size) {
+		mm_heap = &memmap.buffer;
+		array_size = ARRAY_SIZE(buf_heap_map);
+#if (HEAP_DMA_BUFFER_SIZE > 0)
+	} else if ((uint32_t)ptr >= memmap.dma.heap &&
+		(uint32_t)ptr < memmap.dma.heap + memmap.dma.size) {
+		mm_heap = &memmap.dma;
+		array_size = ARRAY_SIZE(dma_buf_heap_map);
+#endif
+	} else
+		return;
+
 	/* find block that ptr belongs to */
-	for (i = 0; i < ARRAY_SIZE(rt_heap_map) - 1; i ++) {
+	for (i = 0; i < array_size - 1; i ++) {
 
 		/* is ptr in this block */
-		if ((uint32_t)ptr >= rt_heap_map[i].base &&
-			(uint32_t)ptr < rt_heap_map[i + 1].base)
+		if ((uint32_t)ptr < mm_heap->map[i + 1].base)
 			goto found;
 	}
 
@@ -356,27 +374,29 @@ static void free_block(struct mm_heap *heap, void *ptr)
 	return;
 
 found:
+	/* the block i is it */
+	block_map = &mm_heap->map[i];
+
 	/* calculate block header */
-	map = &rt_heap_map[i];
-	block = ((uint32_t)ptr - map->base) / map->block_size;
-	hdr = &map->block[block];
+	block = ((uint32_t)ptr - block_map->base) / block_map->block_size;
+	hdr = &block_map->block[block];
 
 	/* free block header and continious blocks */
 	for (i = block; i < block + hdr->size; i++) {
-		hdr = &map->block[i];
+		hdr = &block_map->block[i];
 		hdr->size = 0;
 		hdr->flags = 0;
-		map->free_count++;
-		heap->info.used -= map->block_size;
-		heap->info.free += map->block_size;
+		block_map->free_count++;
+		heap->info.used -= block_map->block_size;
+		heap->info.free += block_map->block_size;
 	}
 
 	/* set first free */
-	if (block < map->first_free)
-		map->first_free = block;
+	if (block < block_map->first_free)
+		block_map->first_free = block;
 
 #if DEBUG_BLOCK_FREE
-	alloc_memset_region(ptr, map->block_size * (i - 1), DEBUG_BLOCK_FREE_VALUE);
+	alloc_memset_region(ptr, block_map->block_size * (i - 1), DEBUG_BLOCK_FREE_VALUE);
 #endif
 }
 
@@ -443,47 +463,57 @@ void *rzalloc(int zone, int bflags, size_t bytes)
 /* allocates continuous buffer on 1k boundary */
 void *rballoc(int zone, int bflags, size_t bytes)
 {
+	struct block_map * block_map = buf_heap_map;
+	struct mm_heap * mm_heap = &memmap.buffer;
+	int i, array_size = ARRAY_SIZE(buf_heap_map);
 	uint32_t flags;
 	void *ptr = NULL;
-	int i;
 
+#if (HEAP_DMA_BUFFER_SIZE > 0)
+	if (bflags & RFLAGS_DMA) {
+		mm_heap = &memmap.dma;
+		block_map = dma_buf_heap_map;
+		array_size = ARRAY_SIZE(dma_buf_heap_map);
+	}
+#endif
 	spin_lock_irq(&memmap.lock, flags);
 
 	/* will request fit in single block */
-	for (i = 0; i < ARRAY_SIZE(buf_heap_map); i++) {
+	for (i = 0; i < array_size; i++) {
 
+		trace_value(block_map[i].block_size);
 		/* is block big enough */
-		if (buf_heap_map[i].block_size < bytes)
+		if (block_map[i].block_size < bytes)
 			continue;
 
 		/* does block have free space */
-		if (buf_heap_map[i].free_count == 0)
+		if (block_map[i].free_count == 0)
 			continue;
 
 		/* allocate block */
-		ptr = alloc_block(&memmap.buffer, i, bflags);
+		ptr = alloc_block(mm_heap, i, bflags);
 		goto out;
 	}
 
 	/* request spans > 1 block */
 
 	/* only 1 choice for block size */
-	if (ARRAY_SIZE(buf_heap_map) == 1) {
-		ptr = alloc_cont_blocks(&memmap.buffer, 0, bflags, bytes);
+	if (array_size == 1) {
+		ptr = alloc_cont_blocks(mm_heap, 0, bflags, bytes);
 		goto out;
 	} else {
 
 		/* find best block size for request */
-		for (i = 0; i < ARRAY_SIZE(buf_heap_map); i++) {
+		for (i = 0; i < array_size; i++) {
 
 			/* allocate is block size smaller than request */
-			if (buf_heap_map[i].block_size < bytes)
-				alloc_cont_blocks(&memmap.buffer, i, bflags,
+			if (block_map[i].block_size < bytes)
+				alloc_cont_blocks(mm_heap, i, bflags,
 					bytes);
 		}
 	}
 
-	ptr = alloc_cont_blocks(&memmap.buffer, ARRAY_SIZE(buf_heap_map) - 1,
+	ptr = alloc_cont_blocks(mm_heap, array_size - 1,
 		bflags, bytes);
 
 out:
-- 
2.11.0



More information about the Sound-open-firmware mailing list