Skip to content

Commit 9ddd4e3

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 a6d6c5d commit 9ddd4e3

2 files changed

Lines changed: 76 additions & 16 deletions

File tree

src/audio/module_adapter/module_adapter.c

Lines changed: 75 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,112 @@ 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,
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 | SOF_MEM_FLAG_USER;
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_new(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 = SOF_MEM_FLAG_USER;
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+
* Would be difficult to optimize the allocation to use cache. Only if
115+
* the whole currently active topology is running on the primary core,
116+
* then it can be cached. Effectively it can be only cached in
117+
* single-core configurations.
118+
*/
119+
struct comp_dev *dev = sof_heap_alloc(mod_heap, SOF_MEM_FLAG_COHERENT, sizeof(*dev), 0);
120+
121+
if (!dev) {
122+
comp_cl_err(drv, "failed to allocate memory for comp_dev");
123+
goto err;
124+
}
125+
126+
memset(dev, 0, sizeof(*dev));
127+
comp_init(drv, dev, sizeof(*dev));
74128
dev->ipc_config = *config;
75129
mod->dev = dev;
76130
dev->mod = mod;
77131

78132
return mod;
79133

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

83140
return NULL;
84141
}
85142

86143
static void module_adapter_mem_free(struct processing_module *mod)
87144
{
88-
const struct comp_driver *drv = mod->dev->drv;
145+
struct k_heap *mod_heap = mod->priv.resources.heap;
89146

90147
#if CONFIG_IPC_MAJOR_4
148+
const struct comp_driver *drv = mod->dev->drv;
149+
91150
sof_heap_free(drv->user_heap, mod->priv.cfg.input_pins);
92151
#endif
93-
sof_heap_free(drv->user_heap, mod->dev);
94-
sof_heap_free(drv->user_heap, mod);
152+
sof_heap_free(mod_heap, mod->dev);
153+
sof_heap_free(mod_heap, mod);
95154
}
96155

97156
/*

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)