Skip to content

Commit 15cc9b1

Browse files
committed
module-adapter: allocate control objects on an own heap
We want to be able to serve all module memory allocations from a private heap. This commit creates such a heap for DP scheduled modules and moves struct comp_dev and struct processing_module to it. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
1 parent e1c78d4 commit 15cc9b1

3 files changed

Lines changed: 81 additions & 16 deletions

File tree

src/audio/module_adapter/module_adapter.c

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <sof/platform.h>
2424
#include <sof/ut.h>
2525
#include <rtos/interrupt.h>
26+
#include <rtos/kernel.h>
2627
#include <rtos/symbol.h>
2728
#include <limits.h>
2829
#include <stdint.h>
@@ -44,54 +45,111 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv,
4445
return module_adapter_new_ext(drv, config, spec, NULL, NULL);
4546
}
4647

47-
static struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv,
48-
const struct comp_ipc_config *config)
48+
#if CONFIG_MM_DRV
49+
#define PAGE_SZ CONFIG_MM_DRV_PAGE_SIZE
50+
#else
51+
#include <platform/platform.h>
52+
#define PAGE_SZ HOST_PAGE_SIZE
53+
#endif
54+
55+
static struct k_heap *module_adapter_dp_heap(const struct comp_ipc_config *config,
56+
uint32_t *flags)
4957
{
50-
struct comp_dev *dev = comp_alloc(drv, sizeof(*dev));
58+
/* src-lite with 8 channels has been seen allocating 14k in one go */
59+
/* FIXME: the size will be derived from configuration */
60+
const size_t heap_size = 20 * 1024;
5161

52-
if (!dev) {
53-
comp_cl_err(drv, "failed to allocate memory for comp_dev");
62+
/* Keep uncached to match the default SOF heap! */
63+
uint8_t *mod_heap_mem = rballoc_align(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT,
64+
heap_size, PAGE_SZ);
65+
66+
if (!mod_heap_mem)
5467
return NULL;
55-
}
5668

57-
/* allocate module information.
69+
struct k_heap *mod_heap = (struct k_heap *)mod_heap_mem;
70+
const size_t heap_prefix_size = ALIGN_UP(sizeof(*mod_heap), 8);
71+
void *mod_heap_buf = mod_heap_mem + heap_prefix_size;
72+
73+
k_heap_init(mod_heap, mod_heap_buf, heap_size - heap_prefix_size);
74+
/*
5875
* for DP shared modules this struct must be accessible from all cores
5976
* Unfortunately at this point there's no information of components the module
6077
* will be bound to. So we need to allocate shared memory for each DP module
6178
* To be removed when pipeline 2.0 is ready
6279
*/
63-
int flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ?
64-
SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER;
80+
*flags = SOF_MEM_FLAG_COHERENT;
6581

66-
struct processing_module *mod = sof_heap_alloc(drv->user_heap, flags, sizeof(*mod), 0);
82+
return mod_heap;
83+
}
84+
85+
static struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv,
86+
const struct comp_ipc_config *config)
87+
{
88+
struct k_heap *mod_heap;
89+
uint32_t flags;
90+
91+
if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP && IS_ENABLED(CONFIG_USERSPACE) &&
92+
!IS_ENABLED(CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP)) {
93+
mod_heap = module_adapter_dp_heap(config, &flags);
94+
if (!mod_heap) {
95+
comp_cl_err(drv, "Failed to allocate DP module heap");
96+
return NULL;
97+
}
98+
} else {
99+
flags = 0;
100+
mod_heap = drv->user_heap;
101+
}
102+
103+
struct processing_module *mod = sof_heap_alloc(mod_heap, flags, sizeof(*mod), 0);
67104

68105
if (!mod) {
69-
comp_err(dev, "failed to allocate memory for module");
70-
goto err;
106+
comp_cl_err(drv, "failed to allocate memory for module");
107+
goto emod;
71108
}
72109

73110
memset(mod, 0, sizeof(*mod));
111+
mod->priv.resources.heap = mod_heap;
112+
113+
/*
114+
* comp_alloc() always allocated dev uncached. Would be difficult to optimize. Only
115+
* if the whole currently active topology is running on the primary core, then it
116+
* can be cached. Effectively it can be only cached in single-core configurations.
117+
*/
118+
struct comp_dev *dev = sof_heap_alloc(mod_heap, SOF_MEM_FLAG_COHERENT, sizeof(*dev), 0);
119+
120+
if (!dev) {
121+
comp_cl_err(drv, "failed to allocate memory for comp_dev");
122+
goto err;
123+
}
124+
125+
memset(dev, 0, sizeof(*dev));
126+
comp_init(drv, dev, sizeof(*dev));
74127
dev->ipc_config = *config;
75128
mod->dev = dev;
76129
dev->mod = mod;
77130

78131
return mod;
79132

80133
err:
81-
sof_heap_free(drv->user_heap, dev);
134+
sof_heap_free(mod_heap, mod);
135+
emod:
136+
if (mod_heap != drv->user_heap)
137+
rfree(mod_heap);
82138

83139
return NULL;
84140
}
85141

86142
static void module_adapter_mem_free(struct processing_module *mod)
87143
{
88-
const struct comp_driver *drv = mod->dev->drv;
144+
struct k_heap *mod_heap = mod->priv.resources.heap;
89145

90146
#if CONFIG_IPC_MAJOR_4
147+
const struct comp_driver *drv = mod->dev->drv;
148+
91149
sof_heap_free(drv->user_heap, mod->priv.cfg.input_pins);
92150
#endif
93-
sof_heap_free(drv->user_heap, mod->dev);
94-
sof_heap_free(drv->user_heap, mod);
151+
sof_heap_free(mod_heap, mod->dev);
152+
sof_heap_free(mod_heap, mod);
95153
}
96154

97155
/*

src/include/sof/audio/module_adapter/module/generic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ struct module_resources {
132132
struct list_item cont_chunk_list; /**< Memory container chunks */
133133
size_t heap_usage;
134134
size_t heap_high_water_mark;
135+
struct k_heap *heap;
135136
#if CONFIG_MODULE_MEMORY_API_DEBUG && defined(__ZEPHYR__)
136137
k_tid_t rsrc_mngr;
137138
#endif

zephyr/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ config SOF_USERSPACE_USE_SHARED_HEAP
4545
When set a shared heap will be used for audio buffers between SOF
4646
kernel and userspace modules.
4747

48+
config SOF_USERSPACE_USE_DRIVER_HEAP
49+
bool "Use driver heap for SOF userspace modules"
50+
depends on USERSPACE
51+
help
52+
When set driver heaps will be used for all SOF userspace modules.
53+
4854
config SOF_ZEPHYR_SHARED_BUFFER_HEAP_SIZE
4955
hex "Size of the shared buffer heap for SOF userspace modules"
5056
default 0x0 if !SOF_USERSPACE_USE_SHARED_HEAP

0 commit comments

Comments
 (0)