Skip to content

Commit 1302a2b

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 d877db5 commit 1302a2b

2 files changed

Lines changed: 79 additions & 20 deletions

File tree

src/audio/module_adapter/module_adapter.c

Lines changed: 78 additions & 20 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_new(const struct comp_ipc_config *config)
4956
{
50-
struct comp_dev *dev = comp_alloc(drv, sizeof(*dev));
57+
/* src-lite with 8 channels has been seen allocating 14k in one go */
58+
/* FIXME: the size will be derived from configuration */
59+
const size_t heap_size = 20 * 1024;
5160

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

57-
/* allocate module information.
58-
* for DP shared modules this struct must be accessible from all cores
59-
* Unfortunately at this point there's no information of components the module
60-
* will be bound to. So we need to allocate shared memory for each DP module
61-
* To be removed when pipeline 2.0 is ready
68+
struct k_heap *mod_heap = (struct k_heap *)mod_heap_mem;
69+
const size_t heap_prefix_size = ALIGN_UP(sizeof(*mod_heap), 8);
70+
void *mod_heap_buf = mod_heap_mem + heap_prefix_size;
71+
72+
k_heap_init(mod_heap, mod_heap_buf, heap_size - heap_prefix_size);
73+
74+
return mod_heap;
75+
}
76+
77+
static struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv,
78+
const struct comp_ipc_config *config)
79+
{
80+
struct k_heap *mod_heap;
81+
/*
82+
* For DP shared modules the struct processing_module object must be
83+
* accessible from all cores. Unfortunately at this point there's no
84+
* information of components the module will be bound to. So we need to
85+
* allocate shared memory for each DP module.
86+
* To be removed when pipeline 2.0 is ready.
6287
*/
63-
int flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ?
64-
SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER;
88+
uint32_t flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ?
89+
SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER;
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_new(config);
94+
if (!mod_heap) {
95+
comp_cl_err(drv, "Failed to allocate DP module heap");
96+
return NULL;
97+
}
98+
} else {
99+
mod_heap = drv->user_heap;
100+
}
65101

66-
struct processing_module *mod = sof_heap_alloc(drv->user_heap, flags, sizeof(*mod), 0);
102+
struct processing_module *mod = sof_heap_alloc(mod_heap, flags, sizeof(*mod), 0);
67103

68104
if (!mod) {
69-
comp_err(dev, "failed to allocate memory for module");
70-
goto err;
105+
comp_cl_err(drv, "failed to allocate memory for module");
106+
goto emod;
71107
}
72108

73109
memset(mod, 0, sizeof(*mod));
110+
mod->priv.resources.heap = mod_heap;
111+
112+
/*
113+
* Would be difficult to optimize the allocation to use cache. Only if
114+
* the whole currently active topology is running on the primary core,
115+
* then it can be cached. Effectively it can be only cached in
116+
* 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

0 commit comments

Comments
 (0)