alloc: Handle operations on shared heap

New memory zone needs dedicated heap routines.

Signed-off-by: Karol Trzcinski <karolx.trzcinski@linux.intel.com>
This commit is contained in:
Karol Trzcinski 2020-09-24 18:20:07 +02:00 committed by Liam Girdwood
parent 43124daf39
commit 489bff14e1
1 changed files with 58 additions and 6 deletions

View File

@ -346,6 +346,12 @@ static struct mm_heap *get_heap_from_ptr(void *ptr)
if (heap)
goto out;
#if CONFIG_CORE_COUNT > 1
heap = find_in_heap_arr(memmap->runtime_shared, PLATFORM_HEAP_RUNTIME_SHARED, ptr);
if (heap)
goto out;
#endif
heap = find_in_heap_arr(memmap->buffer, PLATFORM_HEAP_BUFFER, ptr);
if (heap)
goto out;
@ -660,6 +666,25 @@ static void *rmalloc_runtime(uint32_t flags, uint32_t caps, size_t bytes)
PLATFORM_DCACHE_ALIGN);
}
#if CONFIG_CORE_COUNT > 1
/* allocate single block for shared */
static void *rmalloc_runtime_shared(uint32_t flags, uint32_t caps, size_t bytes)
{
struct mm *memmap = memmap_get();
struct mm_heap *heap;
/* check shared heap for capabilities */
heap = get_heap_from_caps(memmap->runtime_shared, PLATFORM_HEAP_RUNTIME_SHARED, caps);
platform_shared_commit(memmap, sizeof(*memmap));
if (!heap) {
tr_err(&mem_tr, "rmalloc_runtime_shared(): caps = %x, bytes = %d", caps, bytes);
return NULL;
}
return get_ptr_from_heap(heap, flags, caps, bytes, PLATFORM_DCACHE_ALIGN);
}
#endif
static void *_malloc_unlocked(enum mem_zone zone, uint32_t flags, uint32_t caps,
size_t bytes)
{
@ -676,6 +701,22 @@ static void *_malloc_unlocked(enum mem_zone zone, uint32_t flags, uint32_t caps,
case SOF_MEM_ZONE_RUNTIME:
ptr = rmalloc_runtime(flags, caps, bytes);
break;
#if CONFIG_CORE_COUNT > 1
case SOF_MEM_ZONE_RUNTIME_SHARED:
ptr = rmalloc_runtime_shared(flags, caps, bytes);
break;
case SOF_MEM_ZONE_SYS_SHARED:
ptr = rmalloc_sys(memmap->system_shared, flags, caps, bytes);
break;
#else
case SOF_MEM_ZONE_RUNTIME_SHARED:
ptr = rmalloc_runtime(flags, caps, bytes);
break;
case SOF_MEM_ZONE_SYS_SHARED:
ptr = rmalloc_sys(memmap->system, flags, caps, bytes);
break;
#endif
default:
tr_err(&mem_tr, "rmalloc(): invalid zone");
panic(SOF_IPC_PANIC_MEM); /* logic non recoverable problem */
@ -868,7 +909,7 @@ void *rballoc_align(uint32_t flags, uint32_t caps, size_t bytes,
static void _rfree_unlocked(void *ptr)
{
struct mm *memmap = memmap_get();
struct mm_heap *cpu_heap;
struct mm_heap *heap;
/* sanity check - NULL ptrs are fine */
if (!ptr)
@ -877,12 +918,19 @@ static void _rfree_unlocked(void *ptr)
/* prepare pointer if it's platform requirement */
ptr = platform_rfree_prepare(ptr);
/* use the heap dedicated for the selected core */
cpu_heap = memmap->system + cpu_get_id();
/* use the heap dedicated for the core or shared memory */
#if CONFIG_CORE_COUNT > 1
if (is_uncached(ptr))
heap = memmap->system_shared;
else
heap = memmap->system + cpu_get_id();
#else
heap = memmap->system;
#endif
/* panic if pointer is from system heap */
if (ptr >= (void *)cpu_heap->heap &&
(char *)ptr < (char *)cpu_heap->heap + cpu_heap->size) {
if (ptr >= (void *)heap->heap &&
(char *)ptr < (char *)heap->heap + heap->size) {
tr_err(&mem_tr, "rfree(): attempt to free system heap = %p, cpu = %d",
ptr, cpu_get_id());
panic(SOF_IPC_PANIC_MEM);
@ -892,7 +940,7 @@ static void _rfree_unlocked(void *ptr)
free_block(ptr);
memmap->heap_trace_updated = 1;
platform_shared_commit(cpu_heap, sizeof(*cpu_heap));
platform_shared_commit(heap, sizeof(*heap));
platform_shared_commit(memmap, sizeof(*memmap));
}
@ -1050,6 +1098,10 @@ void init_heap(struct sof *sof)
init_heap_map(memmap->runtime, PLATFORM_HEAP_RUNTIME);
#if CONFIG_CORE_COUNT > 1
init_heap_map(memmap->runtime_shared, PLATFORM_HEAP_RUNTIME_SHARED);
#endif
init_heap_map(memmap->buffer, PLATFORM_HEAP_BUFFER);
#if CONFIG_DEBUG_BLOCK_FREE