Skip to content

Commit 08e2284

Browse files
mem: allow virtual heaps to be cross-core
In case of cross core buffers a buffer may be allocated and freed by diffrent core, depending on which component is deleted second. As all control structures of virtual heaps are stored in uncached aliases, there's no technical problems with allowing virtual heaps to work cross core. The only consideration is that in case of cross core allocate/free the cache invalidation MUST be performed on the core that was storing data. It is up to the memory user to ensure this Signed-off-by: Marcin Szkudlinski <marcin.szkudlinski@intel.com>
1 parent ffe184e commit 08e2284

File tree

4 files changed

+23
-45
lines changed

4 files changed

+23
-45
lines changed

zephyr/include/sof/lib/regions_mm.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
* governed by sys_mem_blocks API.
5959
* @var allocation_sizes[] a table of bit arrays representing sizes of allocations
6060
* made in physical_blocks_allocators directly related to physical_blocks_allocators
61-
* @var core_id id of the core that heap was created on
6261
* @var allocating_continuously configuration value deciding if heap allocations
6362
* will be contiguous or single block.
6463
*/
@@ -67,7 +66,6 @@ struct vmh_heap {
6766
const struct sys_mm_drv_region *virtual_region;
6867
struct sys_mem_blocks *physical_blocks_allocators[MAX_MEMORY_ALLOCATORS_COUNT];
6968
struct sys_bitarray *allocation_sizes[MAX_MEMORY_ALLOCATORS_COUNT];
70-
int core_id;
7169
bool allocating_continuously;
7270
};
7371

@@ -105,15 +103,15 @@ struct vmh_heap_config {
105103
};
106104

107105
struct vmh_heap *vmh_init_heap(const struct vmh_heap_config *cfg,
108-
int memory_region_attribute, int core_id, bool allocating_continuously);
106+
int memory_region_attribute, bool allocating_continuously);
109107
void *vmh_alloc(struct vmh_heap *heap, uint32_t alloc_size);
110108
int vmh_free_heap(struct vmh_heap *heap);
111109
int vmh_free(struct vmh_heap *heap, void *ptr);
112110
struct vmh_heap *vmh_reconfigure_heap(struct vmh_heap *heap,
113-
struct vmh_heap_config *cfg, int core_id, bool allocating_continuously);
111+
struct vmh_heap_config *cfg, bool allocating_continuously);
114112
void vmh_get_default_heap_config(const struct sys_mm_drv_region *region,
115113
struct vmh_heap_config *cfg);
116-
struct vmh_heap *vmh_get_heap_by_attribute(uint32_t attr, uint32_t core_id);
114+
struct vmh_heap *vmh_get_heap_by_attribute(uint32_t attr);
117115
/**
118116
* @brief Checks if ptr is in range of given memory range
119117
*

zephyr/lib/alloc.c

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#if CONFIG_VIRTUAL_HEAP
2222
#include <sof/lib/regions_mm.h>
2323

24-
struct vmh_heap *virtual_buffers_heap[CONFIG_MP_MAX_NUM_CPUS];
24+
struct vmh_heap *virtual_buffers_heap;
2525
struct k_spinlock vmh_lock;
2626

2727
#undef HEAPMEM_SIZE
@@ -251,12 +251,11 @@ static bool is_virtual_heap_pointer(void *ptr)
251251

252252
static void virtual_heap_free(void *ptr)
253253
{
254-
struct vmh_heap *const heap = virtual_buffers_heap[cpu_get_id()];
255254
int ret;
256255

257256
ptr = (__sparse_force void *)sys_cache_cached_ptr_get(ptr);
258257

259-
ret = vmh_free(heap, ptr);
258+
ret = vmh_free(virtual_buffers_heap, ptr);
260259
if (ret) {
261260
tr_err(&zephyr_tr, "Unable to free %p! %d", ptr, ret);
262261
k_panic();
@@ -279,17 +278,11 @@ static const struct vmh_heap_config static_hp_buffers = {
279278

280279
static int virtual_heap_init(void)
281280
{
282-
int core;
283-
284281
k_spinlock_init(&vmh_lock);
285-
286-
for (core = 0; core < CONFIG_MP_MAX_NUM_CPUS; core++) {
287-
struct vmh_heap *heap = vmh_init_heap(&static_hp_buffers, MEM_REG_ATTR_CORE_HEAP,
288-
core, false);
289-
if (!heap)
290-
tr_err(&zephyr_tr, "Unable to init virtual heap for core %d!", core);
291-
292-
virtual_buffers_heap[core] = heap;
282+
virtual_buffers_heap = vmh_init_heap(&static_hp_buffers, MEM_REG_ATTR_CORE_HEAP, false);
283+
if (!virtual_buffers_heap) {
284+
tr_err(&zephyr_tr, "Unable to init virtual heap");
285+
return -ENOMEM;
293286
}
294287

295288
return 0;
@@ -490,9 +483,6 @@ EXPORT_SYMBOL(rzalloc);
490483
void *rballoc_align(uint32_t flags, uint32_t caps, size_t bytes,
491484
uint32_t align)
492485
{
493-
#if CONFIG_VIRTUAL_HEAP
494-
struct vmh_heap *virtual_heap;
495-
#endif
496486
struct k_heap *heap;
497487

498488
/* choose a heap */
@@ -510,9 +500,8 @@ void *rballoc_align(uint32_t flags, uint32_t caps, size_t bytes,
510500

511501
#if CONFIG_VIRTUAL_HEAP
512502
/* Use virtual heap if it is available */
513-
virtual_heap = virtual_buffers_heap[cpu_get_id()];
514-
if (virtual_heap)
515-
return virtual_heap_alloc(virtual_heap, flags, caps, bytes, align);
503+
if (virtual_buffers_heap)
504+
return virtual_heap_alloc(virtual_buffers_heap, flags, caps, bytes, align);
516505
#endif /* CONFIG_VIRTUAL_HEAP */
517506

518507
if (flags & SOF_MEM_FLAG_COHERENT)

zephyr/lib/regions_mm.c

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ static struct list_item vmh_list = LIST_INIT(vmh_list);
2828
* @retval NULL on creation failure.
2929
*/
3030
struct vmh_heap *vmh_init_heap(const struct vmh_heap_config *cfg,
31-
int memory_region_attribute, int core_id, bool allocating_continuously)
31+
int memory_region_attribute, bool allocating_continuously)
3232
{
3333
const struct sys_mm_drv_region *virtual_memory_regions =
3434
sys_mm_drv_query_memory_regions();
3535
int i;
3636

3737
/* Check if we haven't created heap for this region already */
38-
if (vmh_get_heap_by_attribute(memory_region_attribute, core_id))
38+
if (vmh_get_heap_by_attribute(memory_region_attribute))
3939
return NULL;
4040

4141
struct vmh_heap *new_heap =
@@ -44,7 +44,6 @@ struct vmh_heap *vmh_init_heap(const struct vmh_heap_config *cfg,
4444
if (!new_heap)
4545
return NULL;
4646

47-
new_heap->core_id = core_id;
4847
list_init(&new_heap->node);
4948
struct vmh_heap_config new_config = {0};
5049

@@ -54,7 +53,7 @@ struct vmh_heap *vmh_init_heap(const struct vmh_heap_config *cfg,
5453
* available cores
5554
*/
5655
if (memory_region_attribute == MEM_REG_ATTR_CORE_HEAP) {
57-
new_heap->virtual_region = &virtual_memory_regions[core_id];
56+
new_heap->virtual_region = &virtual_memory_regions[0];
5857
} else {
5958
for (i = CONFIG_MP_MAX_NUM_CPUS;
6059
i < CONFIG_MP_MAX_NUM_CPUS + VIRTUAL_REGION_COUNT; i++) {
@@ -393,8 +392,6 @@ void *vmh_alloc(struct vmh_heap *heap, uint32_t alloc_size)
393392
if (!alloc_size)
394393
return NULL;
395394
/* Only operations on the same core are allowed */
396-
if (heap->core_id != cpu_get_id())
397-
return NULL;
398395

399396
void *ptr = NULL;
400397
int mem_block_iterator, allocation_error_code = -ENOMEM;
@@ -560,9 +557,6 @@ int vmh_free(struct vmh_heap *heap, void *ptr)
560557
{
561558
int retval;
562559

563-
if (heap->core_id != cpu_get_id())
564-
return -EINVAL;
565-
566560
size_t mem_block_iter, i, size_to_free, block_size, ptr_bit_array_offset,
567561
ptr_bit_array_position, blocks_to_free;
568562
bool ptr_range_found;
@@ -691,15 +685,14 @@ int vmh_free(struct vmh_heap *heap, void *ptr)
691685
* @retval NULL when reconfiguration failed
692686
*/
693687
struct vmh_heap *vmh_reconfigure_heap(
694-
struct vmh_heap *heap, struct vmh_heap_config *cfg,
695-
int core_id, bool allocating_continuously)
688+
struct vmh_heap *heap, struct vmh_heap_config *cfg, bool allocating_continuously)
696689
{
697690
uint32_t region_attribute = heap->virtual_region->attr;
698691

699692
if (vmh_free_heap(heap))
700693
return NULL;
701694

702-
return vmh_init_heap(cfg, region_attribute, core_id, allocating_continuously);
695+
return vmh_init_heap(cfg, region_attribute, allocating_continuously);
703696
}
704697

705698
/**
@@ -740,7 +733,7 @@ void vmh_get_default_heap_config(const struct sys_mm_drv_region *region,
740733
* @retval heap ptr on success
741734
* @retval NULL if there was no heap created fitting the attr.
742735
*/
743-
struct vmh_heap *vmh_get_heap_by_attribute(uint32_t attr, uint32_t core_id)
736+
struct vmh_heap *vmh_get_heap_by_attribute(uint32_t attr)
744737
{
745738
struct list_item *vm_heaps_iterator;
746739
struct vmh_heap *retval;
@@ -753,7 +746,7 @@ struct vmh_heap *vmh_get_heap_by_attribute(uint32_t attr, uint32_t core_id)
753746
const struct sys_mm_drv_region *virtual_memory_region =
754747
sys_mm_drv_query_memory_regions();
755748
/* we move ptr to cpu vmr */
756-
virtual_memory_region = &virtual_memory_region[core_id];
749+
virtual_memory_region = &virtual_memory_region[0];
757750

758751
list_for_item(vm_heaps_iterator, &vmh_list) {
759752
retval =

zephyr/test/vmh.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@ LOG_MODULE_DECLARE(sof_boot_test, CONFIG_SOF_LOG_LEVEL);
2121
/* Test creating and freeing a virtual memory heap */
2222
static void test_vmh_init_and_free_heap(int memory_region_attribute,
2323
struct vmh_heap_config *config,
24-
int core_id,
2524
bool allocating_continuously,
2625
bool expect_success)
2726
{
2827
struct vmh_heap *heap = vmh_init_heap(config, memory_region_attribute,
29-
core_id, allocating_continuously);
28+
allocating_continuously);
3029
if (expect_success) {
3130
zassert_not_null(heap,
3231
"Heap initialization expected to succeed but failed");
@@ -146,7 +145,7 @@ static void test_vmh_multiple_allocs(struct vmh_heap *heap, int num_allocs,
146145
static void test_vmh_alloc_multiple_times(bool allocating_continuously)
147146
{
148147
struct vmh_heap *heap =
149-
vmh_init_heap(NULL, MEM_REG_ATTR_CORE_HEAP, 0, allocating_continuously);
148+
vmh_init_heap(NULL, MEM_REG_ATTR_CORE_HEAP, allocating_continuously);
150149

151150
zassert_not_null(heap, "Heap initialization failed");
152151

@@ -170,7 +169,7 @@ static void test_vmh_alloc_multiple_times(bool allocating_continuously)
170169
static void test_vmh_alloc_free(bool allocating_continuously)
171170
{
172171
struct vmh_heap *heap =
173-
vmh_init_heap(NULL, MEM_REG_ATTR_CORE_HEAP, 0, allocating_continuously);
172+
vmh_init_heap(NULL, MEM_REG_ATTR_CORE_HEAP, allocating_continuously);
174173

175174
zassert_not_null(heap, "Heap initialization failed");
176175

@@ -223,7 +222,7 @@ static void test_alloc_on_configured_heap(bool allocating_continuously)
223222

224223
/* Create continuous allocation heap for success test */
225224
struct vmh_heap *heap =
226-
vmh_init_heap(&config, MEM_REG_ATTR_CORE_HEAP, 0, allocating_continuously);
225+
vmh_init_heap(&config, MEM_REG_ATTR_CORE_HEAP, allocating_continuously);
227226

228227
/* Will succeed on continuous and fail with single block alloc */
229228
test_vmh_alloc_free_check(heap, 512, allocating_continuously);
@@ -248,8 +247,7 @@ static void test_vmh_init_all_heaps(void)
248247
if (!virtual_memory_region[i].size)
249248
break;
250249

251-
struct vmh_heap *heap = vmh_init_heap(NULL, virtual_memory_region[i].attr,
252-
i, true);
250+
struct vmh_heap *heap = vmh_init_heap(NULL, virtual_memory_region[i].attr, true);
253251

254252
zassert_not_null(heap, "Heap initialization expected to succeed but failed");
255253

0 commit comments

Comments
 (0)