Skip to content

Commit d2b8891

Browse files
author
Jyri Sarha
committed
pipeline: add alloc context object to pipeline
Replace the bare vregion pointer in struct pipeline with a mod_alloc_ctx object that bundles both the optional vregion and the heap pointer. The alloc context is always created in pipeline_new() and freed symmetrically in pipeline_free(), removing the separate cleanup that was in ipc_pipeline_free(). The pipeline object itself is now allocated through sof_ctx_zalloc() so it resides in the vregion when one is available, falling back to the default heap otherwise. LL modules share the pipeline's alloc context instead of only sharing the raw vregion pointer. A use_ppl_alloc flag gates the sharing to LL modules only, so DP modules continue to create their own vregion and alloc context as before. module_adapter_mem_free() detects whether a module's alloc belongs to its pipeline and either just releases the vregion reference (ppl_alloc case) or tears down the module's own alloc. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
1 parent ae1199e commit d2b8891

4 files changed

Lines changed: 89 additions & 56 deletions

File tree

src/audio/module_adapter/module_adapter.c

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <sof/audio/component.h>
1515
#include <sof/audio/ipc-config.h>
1616
#include <sof/audio/module_adapter/module/generic.h>
17+
#include <sof/ctx_alloc.h>
1718
#include <sof/audio/sink_api.h>
1819
#include <sof/audio/source_api.h>
1920
#include <sof/audio/audio_buffer.h>
@@ -97,7 +98,7 @@ static
9798
struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv,
9899
const struct comp_ipc_config *config,
99100
const struct module_ext_init_data *ext_init,
100-
struct vregion *ppl_vreg)
101+
struct mod_alloc_ctx *ppl_alloc)
101102
{
102103
struct k_heap *mod_heap;
103104
struct vregion *mod_vreg;
@@ -113,6 +114,8 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
113114
uint32_t flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ?
114115
SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER;
115116
size_t heap_size;
117+
bool use_ppl_alloc = ppl_alloc &&
118+
config->proc_domain == COMP_PROCESSING_DOMAIN_LL;
116119

117120
if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP && IS_ENABLED(CONFIG_USERSPACE) &&
118121
!IS_ENABLED(CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP)) {
@@ -122,36 +125,47 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
122125
return NULL;
123126
}
124127
mod_heap = NULL;
125-
} else if (ppl_vreg && config->proc_domain == COMP_PROCESSING_DOMAIN_LL) {
126-
mod_vreg = vregion_get(ppl_vreg);
127-
mod_heap = NULL;
128+
} else if (use_ppl_alloc) {
129+
mod_vreg = ppl_alloc->vreg ? vregion_get(ppl_alloc->vreg) : NULL;
130+
mod_heap = ppl_alloc->heap;
128131
heap_size = 0;
129132
} else {
130133
mod_heap = drv->user_heap;
131134
heap_size = 0;
132135
mod_vreg = NULL;
133136
}
134137

135-
if (!mod_vreg)
138+
if (use_ppl_alloc) {
139+
/* LL modules use the pipeline's alloc context */
140+
mod = sof_ctx_alloc(ppl_alloc, flags, sizeof(*mod), 0);
141+
} else if (!mod_vreg) {
136142
mod = sof_heap_alloc(mod_heap, flags, sizeof(*mod), 0);
137-
else if (flags & SOF_MEM_FLAG_COHERENT)
143+
} else if (flags & SOF_MEM_FLAG_COHERENT) {
138144
mod = vregion_alloc_coherent(mod_vreg, sizeof(*mod));
139-
else
145+
} else {
140146
mod = vregion_alloc(mod_vreg, sizeof(*mod));
147+
}
141148

142149
if (!mod) {
143150
comp_cl_err(drv, "failed to allocate memory for module");
144151
goto emod;
145152
}
146153

147-
struct mod_alloc_ctx *alloc = rzalloc(flags, sizeof(*alloc));
154+
struct mod_alloc_ctx *alloc;
155+
156+
if (use_ppl_alloc) {
157+
/* LL modules share the pipeline's alloc context */
158+
alloc = ppl_alloc;
159+
} else {
160+
alloc = rzalloc(flags, sizeof(*alloc));
161+
if (!alloc)
162+
goto ealloc;
148163

149-
if (!alloc)
150-
goto ealloc;
164+
alloc->heap = mod_heap;
165+
alloc->vreg = mod_vreg;
166+
}
151167

152168
memset(mod, 0, sizeof(*mod));
153-
alloc->heap = mod_heap;
154-
alloc->vreg = mod_vreg;
155169
mod->priv.resources.alloc = alloc;
156170
mod_resource_init(mod);
157171

@@ -161,7 +175,9 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
161175
* then it can be cached. Effectively it can be only cached in
162176
* single-core configurations.
163177
*/
164-
if (mod_vreg)
178+
if (use_ppl_alloc)
179+
dev = sof_ctx_alloc(ppl_alloc, SOF_MEM_FLAG_COHERENT, sizeof(*dev), 0);
180+
else if (mod_vreg)
165181
dev = vregion_alloc_coherent(mod_vreg, sizeof(*dev));
166182
else
167183
dev = sof_heap_alloc(mod_heap, SOF_MEM_FLAG_COHERENT, sizeof(*dev), 0);
@@ -180,42 +196,47 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
180196
return mod;
181197

182198
edev:
183-
rfree(alloc);
199+
if (!use_ppl_alloc)
200+
rfree(alloc);
184201
ealloc:
185-
if (mod_vreg)
202+
if (use_ppl_alloc)
203+
sof_ctx_free(ppl_alloc, mod);
204+
else if (mod_vreg)
186205
vregion_free(mod_vreg, mod);
187206
else
188207
sof_heap_free(mod_heap, mod);
189208
emod:
190-
vregion_put(mod_vreg);
209+
if (use_ppl_alloc)
210+
vregion_put(ppl_alloc->vreg);
211+
else
212+
vregion_put(mod_vreg);
191213

192214
return NULL;
193215
}
194216

195217
static void module_adapter_mem_free(struct processing_module *mod)
196218
{
197219
struct mod_alloc_ctx *alloc = mod->priv.resources.alloc;
198-
struct k_heap *mod_heap = alloc->heap;
220+
bool ppl_alloc = mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL &&
221+
mod->dev->pipeline && mod->dev->pipeline->alloc == alloc;
199222

200223
/*
201224
* In principle it shouldn't even be needed to free individual objects
202225
* on the module heap since we're freeing the heap itself too
203226
*/
204227
#if CONFIG_IPC_MAJOR_4
205-
sof_heap_free(mod_heap, mod->priv.cfg.input_pins);
228+
sof_heap_free(alloc->heap, mod->priv.cfg.input_pins);
206229
#endif
207-
if (alloc->vreg) {
208-
struct vregion *mod_vreg = alloc->vreg;
209-
uint32_t proc_domain = mod->dev->ipc_config.proc_domain;
210-
211-
vregion_free(mod_vreg, mod->dev);
212-
vregion_free(mod_vreg, mod);
213-
/* DP module alloc is freed later, but for LL modules we free it here */
214-
if (!vregion_put(mod_vreg) || proc_domain == COMP_PROCESSING_DOMAIN_LL)
230+
sof_ctx_free(alloc, mod->dev);
231+
sof_ctx_free(alloc, mod);
232+
233+
if (ppl_alloc) {
234+
/* alloc belongs to pipeline, just release vregion reference */
235+
vregion_put(alloc->vreg);
236+
} else if (alloc->vreg) {
237+
if (!vregion_put(alloc->vreg))
215238
rfree(alloc);
216239
} else {
217-
sof_heap_free(mod_heap, mod->dev);
218-
sof_heap_free(mod_heap, mod);
219240
rfree(alloc);
220241
}
221242
}
@@ -268,18 +289,18 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
268289
#if CONFIG_IPC_MAJOR_4
269290
struct ipc_comp_dev *ipc_pipe;
270291
struct ipc *ipc = ipc_get();
271-
struct vregion *ppl_vreg = NULL;
292+
struct mod_alloc_ctx *ppl_alloc = NULL;
272293

273-
/* resolve the pipeline pointer early to pass its vregion to mem_alloc */
294+
/* resolve the pipeline pointer early to pass its alloc to mem_alloc */
274295
ipc_pipe = ipc_get_comp_by_ppl_id(ipc, COMP_TYPE_PIPELINE, config->pipeline_id,
275296
IPC_COMP_IGNORE_REMOTE);
276297
if (ipc_pipe && ipc_pipe->pipeline)
277-
ppl_vreg = ipc_pipe->pipeline->vreg;
298+
ppl_alloc = ipc_pipe->pipeline->alloc;
278299
#endif
279300

280301
struct processing_module *mod = module_adapter_mem_alloc(drv, config, ext_init,
281302
#if CONFIG_IPC_MAJOR_4
282-
ppl_vreg
303+
ppl_alloc
283304
#else
284305
NULL
285306
#endif

src/audio/pipeline/pipeline-graph.c

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <sof/audio/module_adapter/module/generic.h>
1111
#include <sof/audio/pipeline.h>
1212
#include <sof/ipc/msg.h>
13+
#include <sof/ctx_alloc.h>
1314
#include <sof/lib/vregion.h>
1415
#include <rtos/interrupt.h>
1516
#include <rtos/symbol.h>
@@ -115,6 +116,7 @@ void pipeline_posn_init(struct sof *sof)
115116
struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_t priority,
116117
uint32_t comp_id, struct create_pipeline_params *pparams)
117118
{
119+
struct mod_alloc_ctx *alloc;
118120
struct sof_ipc_stream_posn posn;
119121
struct pipeline *p;
120122
int ret;
@@ -125,32 +127,37 @@ struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_
125127
/* show heap status */
126128
heap_trace_all(0);
127129

128-
/* allocate new pipeline */
129-
p = sof_heap_alloc(heap, SOF_MEM_FLAG_USER, sizeof(*p), 0);
130-
if (!p) {
131-
pipe_cl_err("Out of Memory");
130+
alloc = rzalloc(SOF_MEM_FLAG_USER, sizeof(*alloc));
131+
if (!alloc) {
132+
pipe_cl_err("Failed to allocate pipeline alloc context");
132133
return NULL;
133134
}
134135

135-
memset(p, 0, sizeof(*p));
136-
137-
/* init pipeline */
138-
p->heap = heap;
136+
alloc->heap = heap;
139137

138+
/* Create vregion for pipeline and its modules if size info is available */
140139
if (pparams && pparams->mem_data &&
141140
(pparams->mem_data->lifetime_heap_bytes ||
142141
pparams->mem_data->interim_heap_bytes)) {
143142
size_t vr_size = pparams->mem_data->lifetime_heap_bytes +
144143
pparams->mem_data->interim_heap_bytes;
145144

146-
p->vreg = vregion_create(vr_size);
147-
if (!p->vreg) {
148-
pipe_cl_err("Failed to create pipeline vregion of %zu bytes",
145+
alloc->vreg = vregion_create(vr_size);
146+
if (!alloc->vreg)
147+
pipe_cl_err("Failed to create pipeline vregion of %zu bytes, using heap",
149148
vr_size);
150-
goto free;
151-
}
152149
}
153150

151+
p = sof_ctx_zalloc(alloc, SOF_MEM_FLAG_USER, sizeof(*p), 0);
152+
if (!p) {
153+
pipe_cl_err("Out of Memory");
154+
goto free_alloc;
155+
}
156+
157+
/* init pipeline */
158+
p->heap = heap;
159+
p->alloc = alloc;
160+
154161
p->comp_id = comp_id;
155162
p->priority = priority;
156163
p->pipeline_id = pipeline_id;
@@ -183,7 +190,10 @@ struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_
183190

184191
return p;
185192
free:
186-
sof_heap_free(heap, p);
193+
sof_ctx_free(alloc, p);
194+
free_alloc:
195+
vregion_put(alloc->vreg);
196+
rfree(alloc);
187197
return NULL;
188198
}
189199

@@ -256,6 +266,8 @@ void pipeline_disconnect(struct comp_dev *comp, struct comp_buffer *buffer, int
256266
/* pipelines must be inactive */
257267
int pipeline_free(struct pipeline *p)
258268
{
269+
struct mod_alloc_ctx *alloc = p->alloc;
270+
259271
pipe_dbg(p, "entry");
260272

261273
/*
@@ -276,7 +288,12 @@ int pipeline_free(struct pipeline *p)
276288
pipeline_posn_offset_put(p->posn_offset);
277289

278290
/* now free the pipeline */
279-
sof_heap_free(p->heap, p);
291+
sof_ctx_free(alloc, p);
292+
293+
/* free alloc context and vregion */
294+
if (vregion_put(alloc->vreg))
295+
pipe_cl_warn("pipeline vregion still in use");
296+
rfree(alloc);
280297

281298
/* show heap status */
282299
heap_trace_all(0);
@@ -354,8 +371,8 @@ int pipeline_complete(struct pipeline *p, struct comp_dev *source,
354371
p->source_comp = source;
355372
p->sink_comp = sink;
356373

357-
if (p->vreg)
358-
vregion_set_interim(p->vreg);
374+
if (p->alloc && p->alloc->vreg)
375+
vregion_set_interim(p->alloc->vreg);
359376

360377
p->status = COMP_STATE_READY;
361378

src/include/sof/audio/pipeline.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct comp_dev;
2626
struct ipc;
2727
struct ipc_msg;
2828
struct k_heap;
29-
struct vregion;
29+
struct mod_alloc_ctx;
3030

3131
/*
3232
* Pipeline status to stop execution of current path, but to keep the
@@ -55,7 +55,7 @@ struct vregion;
5555
*/
5656
struct pipeline {
5757
struct k_heap *heap; /**< heap used for allocating this pipeline */
58-
struct vregion *vreg; /**< shared vregion for pipeline modules */
58+
struct mod_alloc_ctx *alloc; /**< shared alloc context for pipeline modules */
5959
uint32_t comp_id; /**< component id for pipeline */
6060
uint32_t pipeline_id; /**< pipeline id */
6161
uint32_t sched_id; /**< Scheduling component id */

src/ipc/ipc4/helper.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -513,11 +513,6 @@ __cold int ipc_pipeline_free(struct ipc *ipc, uint32_t comp_id)
513513
return ret;
514514
}
515515

516-
if (ipc_pipe->pipeline->vreg) {
517-
if (vregion_put(ipc_pipe->pipeline->vreg))
518-
tr_warn(&ipc_tr, "pipeline vregion still in use");
519-
}
520-
521516
/* free buffer, delete all tasks and remove from list */
522517
ret = pipeline_free(ipc_pipe->pipeline);
523518
if (ret < 0) {

0 commit comments

Comments
 (0)