Skip to content

Commit 617e49d

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 6f4ce36 commit 617e49d

4 files changed

Lines changed: 50 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
@@ -88,7 +88,8 @@ static struct vregion *module_adapter_dp_heap_new(const struct comp_ipc_config *
8888
static
8989
struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv,
9090
const struct comp_ipc_config *config,
91-
const struct module_ext_init_data *ext_init)
91+
const struct module_ext_init_data *ext_init,
92+
struct vregion *ppl_vreg)
9293
{
9394
struct k_heap *mod_heap;
9495
struct vregion *mod_vreg;
@@ -113,6 +114,10 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
113114
return NULL;
114115
}
115116
mod_heap = NULL;
117+
} else if (ppl_vreg && config->proc_domain == COMP_PROCESSING_DOMAIN_LL) {
118+
mod_vreg = vregion_get(ppl_vreg);
119+
mod_heap = NULL;
120+
heap_size = 0;
116121
} else {
117122
mod_heap = drv->user_heap;
118123
heap_size = 0;
@@ -193,10 +198,12 @@ static void module_adapter_mem_free(struct processing_module *mod)
193198
#endif
194199
if (alloc->vreg) {
195200
struct vregion *mod_vreg = alloc->vreg;
201+
uint32_t proc_domain = mod->dev->ipc_config.proc_domain;
196202

197203
vregion_free(mod_vreg, mod->dev);
198204
vregion_free(mod_vreg, mod);
199-
if (!vregion_put(mod_vreg))
205+
/* DP module alloc is freed later, but for LL modules we free it here */
206+
if (!vregion_put(mod_vreg) || proc_domain == COMP_PROCESSING_DOMAIN_LL)
200207
rfree(alloc);
201208
} else {
202209
sof_heap_free(mod_heap, mod->dev);
@@ -251,7 +258,25 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
251258
NULL;
252259
#endif
253260

254-
struct processing_module *mod = module_adapter_mem_alloc(drv, config, ext_init);
261+
#if CONFIG_IPC_MAJOR_4
262+
struct ipc_comp_dev *ipc_pipe;
263+
struct ipc *ipc = ipc_get();
264+
struct vregion *ppl_vreg = NULL;
265+
266+
/* resolve the pipeline pointer early to pass its vregion to mem_alloc */
267+
ipc_pipe = ipc_get_comp_by_ppl_id(ipc, COMP_TYPE_PIPELINE, config->pipeline_id,
268+
IPC_COMP_IGNORE_REMOTE);
269+
if (ipc_pipe && ipc_pipe->pipeline)
270+
ppl_vreg = ipc_pipe->pipeline->vreg;
271+
#endif
272+
273+
struct processing_module *mod = module_adapter_mem_alloc(drv, config, ext_init,
274+
#if CONFIG_IPC_MAJOR_4
275+
ppl_vreg
276+
#else
277+
NULL
278+
#endif
279+
);
255280

256281
if (!mod)
257282
return NULL;
@@ -310,12 +335,7 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
310335
goto err;
311336

312337
#if CONFIG_IPC_MAJOR_4
313-
struct ipc_comp_dev *ipc_pipe;
314-
struct ipc *ipc = ipc_get();
315-
316338
/* set the pipeline pointer if ipc_pipe is valid */
317-
ipc_pipe = ipc_get_comp_by_ppl_id(ipc, COMP_TYPE_PIPELINE, config->pipeline_id,
318-
IPC_COMP_IGNORE_REMOTE);
319339
if (ipc_pipe) {
320340
dev->pipeline = ipc_pipe->pipeline;
321341

src/audio/pipeline/pipeline-graph.c

Lines changed: 15 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,16 @@ struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_
135136

136137
/* init pipeline */
137138
p->heap = heap;
139+
140+
/* Create vregion for pipeline and its modules if size info is available */
141+
if (IS_ENABLED(CONFIG_SOF_VREGIONS) &&
142+
pparams && pparams->mem_data && pparams->mem_data->heap_bytes) {
143+
alloc->vreg = vregion_create(pparams->mem_data->heap_bytes);
144+
if (!alloc->vreg)
145+
pipe_cl_err("Failed to create pipeline vregion of %zu bytes, using heap",
146+
pparams->mem_data->heap_bytes);
147+
}
148+
138149
p->comp_id = comp_id;
139150
p->priority = priority;
140151
p->pipeline_id = pipeline_id;
@@ -337,6 +348,10 @@ int pipeline_complete(struct pipeline *p, struct comp_dev *source,
337348

338349
p->source_comp = source;
339350
p->sink_comp = sink;
351+
352+
if (p->vreg)
353+
vregion_set_interim(p->vreg);
354+
340355
p->status = COMP_STATE_READY;
341356

342357
/* 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)