Skip to content

Commit 04bc5c1

Browse files
committed
wip: alloc: add scratch & batch heaps on top of virtual pages
WIP: To be split into smaller patches. 1) Add a simple contiguous virtual page allocator. 2) Add a scratch and batch heap on top of pre alloctated virtual pages. 3) Integrate into mod_alloc() and mod_free() to use scratch and batch heaps for runtime and lifetime pipeline data. 4) TODO: Make sure all pipeline resources exist within same virtual region. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
1 parent 1117d0b commit 04bc5c1

9 files changed

Lines changed: 801 additions & 1 deletion

File tree

src/audio/module_adapter/module/generic.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,22 @@ void *mod_alloc_align(struct processing_module *mod, uint32_t size, uint32_t ali
184184
return NULL;
185185
}
186186

187+
#if CONFIG_SOF_PACOVR
188+
/* do we need to use the scratch heap or the batch heap? */
189+
if (mod->priv.state != MODULE_INITIALIZED) {
190+
/* batch allocator */
191+
ptr = pacovr_batch_alloc(mod->dev->pipeline->pacovr, size);
192+
} else {
193+
/* scratch allocator */
194+
ptr = pacovr_scratch_alloc_align(mod->dev->pipeline->pacovr, size, alignment);
195+
}
196+
#else
187197
/* Allocate memory for module */
188198
if (alignment)
189199
ptr = rballoc_align(SOF_MEM_FLAG_USER, size, alignment);
190200
else
191201
ptr = rballoc(SOF_MEM_FLAG_USER, size);
202+
#endif
192203

193204
if (!ptr) {
194205
comp_err(mod->dev, "failed to allocate memory.");
@@ -318,7 +329,18 @@ static int free_contents(struct processing_module *mod, struct module_resource *
318329

319330
switch (container->type) {
320331
case MOD_RES_HEAP:
332+
#if CONFIG_SOF_PACOVR
333+
/* do we need to use the scratch heap or the batch heap? */
334+
if (mod->priv.state != MODULE_INITIALIZED) {
335+
/* batch allocator */
336+
pacovr_batch_free(mod->dev->pipeline->pacovr);
337+
} else {
338+
/* scratch allocator */
339+
pacovr_scratch_free(mod->dev->pipeline->pacovr);
340+
}
341+
#else
321342
rfree(container->ptr);
343+
#endif
322344
res->heap_usage -= container->size;
323345
return 0;
324346
#if CONFIG_COMP_BLOB

src/audio/pipeline/pipeline-graph.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <rtos/interrupt.h>
1313
#include <rtos/symbol.h>
1414
#include <sof/lib/mm_heap.h>
15+
#include <sof/lib/pacovr.h>
1516
#include <sof/lib/uuid.h>
1617
#include <sof/compiler_attributes.h>
1718
#include <sof/list.h>
@@ -127,6 +128,18 @@ struct pipeline *pipeline_new(uint32_t pipeline_id, uint32_t priority, uint32_t
127128
return NULL;
128129
}
129130

131+
#if CONFIG_SOF_PACOVR
132+
/* create a pacovr region for all resources */
133+
// TODO: make batch and scratch sizes configurable from topology
134+
size_t scratch_size = 0x4000; /* 16kB scratch */
135+
size_t batch_size = 0x20000; /* 128kB batch */
136+
p->pacovr = pacovr_create(batch_size, scratch_size);
137+
if (!p->pacovr) {
138+
pipe_err(p, "pipeline_new(): pacovr_create() failed.");
139+
goto free;
140+
}
141+
#endif
142+
130143
/* init pipeline */
131144
p->comp_id = comp_id;
132145
p->priority = priority;
@@ -236,6 +249,10 @@ int pipeline_free(struct pipeline *p)
236249

237250
pipeline_posn_offset_put(p->posn_offset);
238251

252+
#if CONFIG_SOF_PACOVR
253+
/* free pacovr region */
254+
pacovr_destroy(p->pacovr);
255+
#endif
239256
/* now free the pipeline */
240257
rfree(p);
241258

src/include/sof/audio/pipeline.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <sof/lib/cpu.h>
1212
#include <sof/lib/mailbox.h>
13+
#include <sof/lib/pacovr.h>
1314
#include <sof/list.h>
1415
#include <rtos/task.h>
1516
#include <rtos/sof.h>
@@ -64,6 +65,9 @@ struct pipeline {
6465
uint32_t time_domain; /**< scheduling time domain */
6566
uint32_t attributes; /**< pipeline attributes from IPC extension msg/ */
6667

68+
/* pipeline resource management */
69+
struct pacovr *pacovr;
70+
6771
/* runtime status */
6872
int32_t xrun_bytes; /* last xrun length */
6973
uint32_t status; /* pipeline status */

zephyr/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,11 @@ if (CONFIG_SOC_SERIES_INTEL_ADSP_ACE)
288288
)
289289

290290
# Sources for virtual heap management
291-
zephyr_library_sources(
291+
zephyr_library_sources_ifdef(CONFIG_SOF_PACOVR
292+
lib/vpages.c
293+
lib/pacovr.c
294+
)
295+
zephyr_library_sources_ifndef(CONFIG_SOF_PACOVR,
292296
lib/regions_mm.c
293297
)
294298

zephyr/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ config SOF_ZEPHYR_USERSPACE_MODULE_HEAP_SIZE
7676
module has its own independent heap to which only it has access. This heap is
7777
shared between instances of the same module.
7878

79+
config SOF_PACOVR
80+
bool "Enable PACOVR memory allocator"
81+
default y if ACE
82+
default n
83+
depends on ACE
84+
help
85+
Enable the PACOVR memory allocator for pipeline resource management.
86+
PACOVR provides a way to manage memory resources for audio pipelines,
87+
including both batch and scratch allocations.
88+
7989
config ZEPHYR_NATIVE_DRIVERS
8090
bool "Use Zephyr native drivers"
8191
help

zephyr/include/sof/lib/pacovr.h

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
// Copyright(c) 2025 Intel Corporation.
3+
4+
/* Pre Allocated Contiguous Virtual Region */
5+
#ifndef __SOF_LIB_PACOVR_H__
6+
#define __SOF_LIB_PACOVR_H__
7+
8+
#include <zephyr/kernel.h>
9+
#include <stddef.h>
10+
11+
#ifdef __cplusplus
12+
extern "C" {
13+
#endif
14+
15+
struct pacovr;
16+
17+
/**
18+
* @brief Create a new PACOVR instance.
19+
*
20+
* Create a new PACOVR instance with specified batch and scratch sizes. Total
21+
* size is the sum of batch and scratch sizes.
22+
*
23+
* @param[in] batch_size Size of the PACOVR batch region.
24+
* @param[in] scratch_size Size of the scratch heap.
25+
* @return struct pacovr* Pointer to the new PACOVR instance, or NULL on failure.
26+
*/
27+
struct pacovr *pacovr_create(size_t batch_size, size_t scratch_size);
28+
29+
/**
30+
* @brief Destroy a PACOVR instance.
31+
*
32+
* Free all associated resources and deallocate the PACOVR instance.
33+
*
34+
* @param[in] p Pointer to the PACOVR instance to destroy.
35+
*/
36+
void pacovr_destroy(struct pacovr *p);
37+
38+
/**
39+
* @brief Allocate memory from the PACOVR scratch heap.
40+
*
41+
* Allocate memory from the PACOVR scratch heap. Intended use for temporary
42+
* allocations during audio processing. i.e. change of parameters or kcontrols.
43+
*
44+
* @param[in] p Pointer to the PACOVR instance.
45+
* @param[in] size Size of the allocation.
46+
* @return void* Pointer to the allocated memory, or NULL on failure.
47+
*/
48+
void *pacovr_scratch_alloc(struct pacovr *p, size_t size);
49+
50+
/**
51+
* @brief Allocate memory with alignment from the PACOVR scratch heap.
52+
*
53+
* Allocate memory with alignment from the PACOVR scratch heap. Intended use for
54+
* temporary allocations during audio processing. i.e. change of parameters or
55+
* kcontrols.
56+
*
57+
* @param[in] p Pointer to the PACOVR instance.
58+
* @param[in] size Size of the allocation.
59+
* @param[in] align Alignment of the allocation.
60+
* @return void* Pointer to the allocated memory, or NULL on failure.
61+
*/
62+
void *pacovr_scratch_alloc_align(struct pacovr *p, size_t size, size_t align);
63+
64+
/**
65+
* @brief Free memory from the PACOVR scratch heap.
66+
*
67+
* Free memory from the PACOVR scratch heap. Intended use for temporary
68+
* allocations during audio processing. i.e. change of parameters or
69+
* kcontrols.
70+
*
71+
* @param[in] p Pointer to the PACOVR instance.
72+
* @param[in] ptr Pointer to the memory to free.
73+
*/
74+
void pacovr_scratch_free(struct pacovr *p, void *ptr);
75+
76+
/**
77+
* @brief Allocate memory from the PACOVR batch allocator.
78+
*
79+
* Allocate memory from the PACOVR batch allocator. Intended use for
80+
* allocations that persist for the lifetime of the audio processing pipeline.
81+
* i.e. component data, buffers, etc.
82+
*
83+
* @param[in] p Pointer to the PACOVR instance.
84+
* @param[in] size Size of the allocation.
85+
* @param[in] align Alignment of the allocation.
86+
* @return void* Pointer to the allocated memory, or NULL on failure.
87+
*/
88+
void *pacovr_batch_alloc(struct pacovr *p, size_t size);
89+
90+
/**
91+
* @brief Free memory from the PACOVR batch allocator.
92+
*
93+
* Free memory from the PACOVR batch allocator. This is a no-op and is
94+
* intended for tuning and tracking only. Batch allocations are freed
95+
* when the PACOVR instance is destroyed. Any call to this function usually
96+
* means the allocation should have been from the scratch heap.
97+
*
98+
* @param[in] p Pointer to the PACOVR instance.
99+
* @param[in] ptr Pointer to the memory to free.
100+
*/
101+
void pacovr_batch_free(struct pacovr *p, void *ptr);
102+
103+
/**
104+
* @brief Log PACOVR memory usage.
105+
*
106+
* @param[in] p Pointer to the PACOVR instance.
107+
*/
108+
void pacovr_info(struct pacovr *p);
109+
110+
#ifdef __cplusplus
111+
}
112+
#endif
113+
114+
#endif /* __SOF_LIB_PACOVR_H__ */

zephyr/include/sof/lib/vpage.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
// Copyright(c) 2025 Intel Corporation.
3+
4+
/* Virtual Page Allocator API */
5+
#ifndef __SOF_LIB_VPAGE_H__
6+
#define __SOF_LIB_VPAGE_H__
7+
8+
#include <zephyr/kernel.h>
9+
#include <stdint.h>
10+
11+
#ifdef __cplusplus
12+
extern "C" {
13+
#endif
14+
15+
/**
16+
* @brief Allocate virtual pages
17+
* Allocates a specified number of contiguous virtual memory pages.
18+
*
19+
* @param[in] pages Number of 4kB pages to allocate.
20+
*
21+
* @return Pointer to the allocated virtual memory region, or NULL on failure.
22+
*/
23+
void *vpage_alloc(uint32_t pages);
24+
25+
/**
26+
* @brief Free virtual pages
27+
* Frees previously allocated virtual memory pages and unmaps them.
28+
*
29+
* @param[in] ptr Pointer to the memory pages to free.
30+
*/
31+
void vpage_free(void *ptr);
32+
33+
/**
34+
* @brief Initialize virtual page allocator
35+
*
36+
* Initializes a virtual page allocator that manages a virtual memory region
37+
* using a page table and block structures.
38+
*
39+
* @retval 0 if successful.
40+
* @retval -ENOMEM on creation failure.
41+
*/
42+
int vpage_init(void);
43+
44+
#ifdef __cplusplus
45+
}
46+
#endif
47+
48+
#endif /* __SOF_LIB_VPAGE_H__ */

0 commit comments

Comments
 (0)