From 489bff14e199787ecd1b63360fdda5a1f70ce08d Mon Sep 17 00:00:00 2001 From: Karol Trzcinski Date: Thu, 24 Sep 2020 18:20:07 +0200 Subject: [PATCH] alloc: Handle operations on shared heap New memory zone needs dedicated heap routines. Signed-off-by: Karol Trzcinski --- src/lib/alloc.c | 64 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/src/lib/alloc.c b/src/lib/alloc.c index be1958cb8..445ae6372 100644 --- a/src/lib/alloc.c +++ b/src/lib/alloc.c @@ -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