Skip to content

Commit ae1199e

Browse files
author
Jyri Sarha
committed
pipeline: allocate shared vregion for LL modules
Create a per-pipeline vregion in pipeline_new() when the IPC4 pipeline extension payload specifies lifetime or interim heap sizes. The vregion size is the sum of both. Store the vregion pointer in struct pipeline. In module_adapter_new_ext() resolve the pipeline pointer before module_adapter_mem_alloc() so the pipeline's vregion can be passed down. LL modules on a pipeline with a vregion use it as their allocation backend via vregion_get(), instead of the driver's default heap. DP modules continue to create their own per-module vregion. Call vregion_set_interim() for the pipeline vregion in pipeline_complete() to switch the allocator to interim mode after all lifetime allocations are done. Release the pipeline vregion with vregion_put() in ipc_pipeline_free() before calling pipeline_free(). Warn if the refcount does not reach zero, indicating a module still holds a reference. Also fix a pre-existing leak in module_adapter_mem_free(): always free the per-module mod_alloc_ctx for LL modules regardless of the vregion refcount, since alloc is allocated from the system heap, not from the vregion. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
1 parent 7f5fc11 commit ae1199e

4 files changed

Lines changed: 55 additions & 8 deletions

File tree

src/audio/module_adapter/module_adapter.c

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ static struct vregion *module_adapter_dp_heap_new(const struct comp_ipc_config *
9696
static
9797
struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv,
9898
const struct comp_ipc_config *config,
99-
const struct module_ext_init_data *ext_init)
99+
const struct module_ext_init_data *ext_init,
100+
struct vregion *ppl_vreg)
100101
{
101102
struct k_heap *mod_heap;
102103
struct vregion *mod_vreg;
@@ -121,6 +122,10 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
121122
return NULL;
122123
}
123124
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+
heap_size = 0;
124129
} else {
125130
mod_heap = drv->user_heap;
126131
heap_size = 0;
@@ -201,10 +206,12 @@ static void module_adapter_mem_free(struct processing_module *mod)
201206
#endif
202207
if (alloc->vreg) {
203208
struct vregion *mod_vreg = alloc->vreg;
209+
uint32_t proc_domain = mod->dev->ipc_config.proc_domain;
204210

205211
vregion_free(mod_vreg, mod->dev);
206212
vregion_free(mod_vreg, mod);
207-
if (!vregion_put(mod_vreg))
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)
208215
rfree(alloc);
209216
} else {
210217
sof_heap_free(mod_heap, mod->dev);
@@ -258,7 +265,25 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
258265
NULL;
259266
#endif
260267

261-
struct processing_module *mod = module_adapter_mem_alloc(drv, config, ext_init);
268+
#if CONFIG_IPC_MAJOR_4
269+
struct ipc_comp_dev *ipc_pipe;
270+
struct ipc *ipc = ipc_get();
271+
struct vregion *ppl_vreg = NULL;
272+
273+
/* resolve the pipeline pointer early to pass its vregion to mem_alloc */
274+
ipc_pipe = ipc_get_comp_by_ppl_id(ipc, COMP_TYPE_PIPELINE, config->pipeline_id,
275+
IPC_COMP_IGNORE_REMOTE);
276+
if (ipc_pipe && ipc_pipe->pipeline)
277+
ppl_vreg = ipc_pipe->pipeline->vreg;
278+
#endif
279+
280+
struct processing_module *mod = module_adapter_mem_alloc(drv, config, ext_init,
281+
#if CONFIG_IPC_MAJOR_4
282+
ppl_vreg
283+
#else
284+
NULL
285+
#endif
286+
);
262287

263288
if (!mod)
264289
return NULL;
@@ -317,12 +342,7 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
317342
goto err;
318343

319344
#if CONFIG_IPC_MAJOR_4
320-
struct ipc_comp_dev *ipc_pipe;
321-
struct ipc *ipc = ipc_get();
322-
323345
/* set the pipeline pointer if ipc_pipe is valid */
324-
ipc_pipe = ipc_get_comp_by_ppl_id(ipc, COMP_TYPE_PIPELINE, config->pipeline_id,
325-
IPC_COMP_IGNORE_REMOTE);
326346
if (ipc_pipe) {
327347
dev->pipeline = ipc_pipe->pipeline;
328348

src/audio/pipeline/pipeline-graph.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <ipc/stream.h>
2626
#include <ipc/topology.h>
2727
#include <ipc4/module.h>
28+
#include <ipc4/pipeline.h>
2829
#include <errno.h>
2930
#include <stdbool.h>
3031
#include <stddef.h>
@@ -135,6 +136,21 @@ struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_
135136

136137
/* init pipeline */
137138
p->heap = heap;
139+
140+
if (pparams && pparams->mem_data &&
141+
(pparams->mem_data->lifetime_heap_bytes ||
142+
pparams->mem_data->interim_heap_bytes)) {
143+
size_t vr_size = pparams->mem_data->lifetime_heap_bytes +
144+
pparams->mem_data->interim_heap_bytes;
145+
146+
p->vreg = vregion_create(vr_size);
147+
if (!p->vreg) {
148+
pipe_cl_err("Failed to create pipeline vregion of %zu bytes",
149+
vr_size);
150+
goto free;
151+
}
152+
}
153+
138154
p->comp_id = comp_id;
139155
p->priority = priority;
140156
p->pipeline_id = pipeline_id;
@@ -337,6 +353,10 @@ int pipeline_complete(struct pipeline *p, struct comp_dev *source,
337353

338354
p->source_comp = source;
339355
p->sink_comp = sink;
356+
357+
if (p->vreg)
358+
vregion_set_interim(p->vreg);
359+
340360
p->status = COMP_STATE_READY;
341361

342362
/* show heap status */

src/include/sof/audio/pipeline.h

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

3031
/*
3132
* Pipeline status to stop execution of current path, but to keep the
@@ -54,6 +55,7 @@ struct k_heap;
5455
*/
5556
struct pipeline {
5657
struct k_heap *heap; /**< heap used for allocating this pipeline */
58+
struct vregion *vreg; /**< shared vregion for pipeline modules */
5759
uint32_t comp_id; /**< component id for pipeline */
5860
uint32_t pipeline_id; /**< pipeline id */
5961
uint32_t sched_id; /**< Scheduling component id */

src/ipc/ipc4/helper.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,11 @@ __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+
516521
/* free buffer, delete all tasks and remove from list */
517522
ret = pipeline_free(ipc_pipe->pipeline);
518523
if (ret < 0) {

0 commit comments

Comments
 (0)