Skip to content

Commit d4d8e5f

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 617e49d commit d4d8e5f

4 files changed

Lines changed: 83 additions & 51 deletions

File tree

src/audio/module_adapter/module_adapter.c

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ static
8989
struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv,
9090
const struct comp_ipc_config *config,
9191
const struct module_ext_init_data *ext_init,
92-
struct vregion *ppl_vreg)
92+
struct mod_alloc_ctx *ppl_alloc)
9393
{
9494
struct k_heap *mod_heap;
9595
struct vregion *mod_vreg;
@@ -105,6 +105,8 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
105105
uint32_t flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ?
106106
SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER;
107107
size_t heap_size;
108+
bool use_ppl_alloc = ppl_alloc &&
109+
config->proc_domain == COMP_PROCESSING_DOMAIN_LL;
108110

109111
if (config->proc_domain == COMP_PROCESSING_DOMAIN_DP && IS_ENABLED(CONFIG_SOF_VREGIONS) &&
110112
IS_ENABLED(CONFIG_USERSPACE) && !IS_ENABLED(CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP)) {
@@ -114,36 +116,47 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
114116
return NULL;
115117
}
116118
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;
119+
} else if (use_ppl_alloc) {
120+
mod_vreg = ppl_alloc->vreg ? vregion_get(ppl_alloc->vreg) : NULL;
121+
mod_heap = ppl_alloc->heap;
120122
heap_size = 0;
121123
} else {
122124
mod_heap = drv->user_heap;
123125
heap_size = 0;
124126
mod_vreg = NULL;
125127
}
126128

127-
if (!mod_vreg)
129+
if (use_ppl_alloc) {
130+
/* LL modules use the pipeline's alloc context */
131+
mod = sof_ctx_alloc(ppl_alloc, flags, sizeof(*mod), 0);
132+
} else if (!mod_vreg) {
128133
mod = sof_heap_alloc(mod_heap, flags, sizeof(*mod), 0);
129-
else if (flags & SOF_MEM_FLAG_COHERENT)
134+
} else if (flags & SOF_MEM_FLAG_COHERENT) {
130135
mod = vregion_alloc_coherent(mod_vreg, sizeof(*mod));
131-
else
136+
} else {
132137
mod = vregion_alloc(mod_vreg, sizeof(*mod));
138+
}
133139

134140
if (!mod) {
135141
comp_cl_err(drv, "failed to allocate memory for module");
136142
goto emod;
137143
}
138144

139-
struct mod_alloc_ctx *alloc = rzalloc(flags, sizeof(*alloc));
145+
struct mod_alloc_ctx *alloc;
146+
147+
if (use_ppl_alloc) {
148+
/* LL modules share the pipeline's alloc context */
149+
alloc = ppl_alloc;
150+
} else {
151+
alloc = rzalloc(flags, sizeof(*alloc));
152+
if (!alloc)
153+
goto ealloc;
140154

141-
if (!alloc)
142-
goto ealloc;
155+
alloc->heap = mod_heap;
156+
alloc->vreg = mod_vreg;
157+
}
143158

144159
memset(mod, 0, sizeof(*mod));
145-
alloc->heap = mod_heap;
146-
alloc->vreg = mod_vreg;
147160
mod->priv.resources.alloc = alloc;
148161
mod_resource_init(mod);
149162

@@ -153,7 +166,9 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
153166
* then it can be cached. Effectively it can be only cached in
154167
* single-core configurations.
155168
*/
156-
if (mod_vreg)
169+
if (use_ppl_alloc)
170+
dev = sof_ctx_alloc(ppl_alloc, SOF_MEM_FLAG_COHERENT, sizeof(*dev), 0);
171+
else if (mod_vreg)
157172
dev = vregion_alloc_coherent(mod_vreg, sizeof(*dev));
158173
else
159174
dev = sof_heap_alloc(mod_heap, SOF_MEM_FLAG_COHERENT, sizeof(*dev), 0);
@@ -172,42 +187,47 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
172187
return mod;
173188

174189
edev:
175-
rfree(alloc);
190+
if (!use_ppl_alloc)
191+
rfree(alloc);
176192
ealloc:
177-
if (mod_vreg)
193+
if (use_ppl_alloc)
194+
sof_ctx_free(ppl_alloc, mod);
195+
else if (mod_vreg)
178196
vregion_free(mod_vreg, mod);
179197
else
180198
sof_heap_free(mod_heap, mod);
181199
emod:
182-
vregion_put(mod_vreg);
200+
if (use_ppl_alloc)
201+
vregion_put(ppl_alloc->vreg);
202+
else
203+
vregion_put(mod_vreg);
183204

184205
return NULL;
185206
}
186207

187208
static void module_adapter_mem_free(struct processing_module *mod)
188209
{
189210
struct mod_alloc_ctx *alloc = mod->priv.resources.alloc;
190-
struct k_heap *mod_heap = alloc->heap;
211+
bool ppl_alloc = mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL &&
212+
mod->dev->pipeline && mod->dev->pipeline->alloc == alloc;
191213

192214
/*
193215
* In principle it shouldn't even be needed to free individual objects
194216
* on the module heap since we're freeing the heap itself too
195217
*/
196218
#if CONFIG_IPC_MAJOR_4
197-
sof_heap_free(mod_heap, mod->priv.cfg.input_pins);
219+
sof_heap_free(alloc->heap, mod->priv.cfg.input_pins);
198220
#endif
199-
if (alloc->vreg) {
200-
struct vregion *mod_vreg = alloc->vreg;
201-
uint32_t proc_domain = mod->dev->ipc_config.proc_domain;
202-
203-
vregion_free(mod_vreg, mod->dev);
204-
vregion_free(mod_vreg, mod);
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)
221+
sof_ctx_free(alloc, mod->dev);
222+
sof_ctx_free(alloc, mod);
223+
224+
if (ppl_alloc) {
225+
/* alloc belongs to pipeline, just release vregion reference */
226+
vregion_put(alloc->vreg);
227+
} else if (alloc->vreg) {
228+
if (!vregion_put(alloc->vreg))
207229
rfree(alloc);
208230
} else {
209-
sof_heap_free(mod_heap, mod->dev);
210-
sof_heap_free(mod_heap, mod);
211231
rfree(alloc);
212232
}
213233
}
@@ -261,18 +281,18 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
261281
#if CONFIG_IPC_MAJOR_4
262282
struct ipc_comp_dev *ipc_pipe;
263283
struct ipc *ipc = ipc_get();
264-
struct vregion *ppl_vreg = NULL;
284+
struct mod_alloc_ctx *ppl_alloc = NULL;
265285

266-
/* resolve the pipeline pointer early to pass its vregion to mem_alloc */
286+
/* resolve the pipeline pointer early to pass its alloc to mem_alloc */
267287
ipc_pipe = ipc_get_comp_by_ppl_id(ipc, COMP_TYPE_PIPELINE, config->pipeline_id,
268288
IPC_COMP_IGNORE_REMOTE);
269289
if (ipc_pipe && ipc_pipe->pipeline)
270-
ppl_vreg = ipc_pipe->pipeline->vreg;
290+
ppl_alloc = ipc_pipe->pipeline->alloc;
271291
#endif
272292

273293
struct processing_module *mod = module_adapter_mem_alloc(drv, config, ext_init,
274294
#if CONFIG_IPC_MAJOR_4
275-
ppl_vreg
295+
ppl_alloc
276296
#else
277297
NULL
278298
#endif

src/audio/pipeline/pipeline-graph.c

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ void pipeline_posn_init(struct sof *sof)
115115
struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_t priority,
116116
uint32_t comp_id, struct create_pipeline_params *pparams)
117117
{
118+
struct mod_alloc_ctx *alloc;
118119
struct sof_ipc_stream_posn posn;
119120
struct pipeline *p;
120121
int ret;
@@ -125,17 +126,13 @@ struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_
125126
/* show heap status */
126127
heap_trace_all(0);
127128

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");
129+
alloc = rzalloc(SOF_MEM_FLAG_USER, sizeof(*alloc));
130+
if (!alloc) {
131+
pipe_cl_err("Failed to allocate pipeline alloc context");
132132
return NULL;
133133
}
134134

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

140137
/* Create vregion for pipeline and its modules if size info is available */
141138
if (IS_ENABLED(CONFIG_SOF_VREGIONS) &&
@@ -146,6 +143,16 @@ struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_
146143
pparams->mem_data->heap_bytes);
147144
}
148145

146+
p = sof_ctx_zalloc(alloc, SOF_MEM_FLAG_USER, sizeof(*p), 0);
147+
if (!p) {
148+
pipe_cl_err("Out of Memory");
149+
goto free_alloc;
150+
}
151+
152+
/* init pipeline */
153+
p->heap = heap;
154+
p->alloc = alloc;
155+
149156
p->comp_id = comp_id;
150157
p->priority = priority;
151158
p->pipeline_id = pipeline_id;
@@ -178,7 +185,10 @@ struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_
178185

179186
return p;
180187
free:
181-
sof_heap_free(heap, p);
188+
sof_ctx_free(alloc, p);
189+
free_alloc:
190+
vregion_put(alloc->vreg);
191+
rfree(alloc);
182192
return NULL;
183193
}
184194

@@ -251,6 +261,8 @@ void pipeline_disconnect(struct comp_dev *comp, struct comp_buffer *buffer, int
251261
/* pipelines must be inactive */
252262
int pipeline_free(struct pipeline *p)
253263
{
264+
struct mod_alloc_ctx *alloc = p->alloc;
265+
254266
pipe_dbg(p, "entry");
255267

256268
/*
@@ -271,7 +283,12 @@ int pipeline_free(struct pipeline *p)
271283
pipeline_posn_offset_put(p->posn_offset);
272284

273285
/* now free the pipeline */
274-
sof_heap_free(p->heap, p);
286+
sof_ctx_free(alloc, p);
287+
288+
/* free alloc context and vregion */
289+
if (vregion_put(alloc->vreg))
290+
pipe_cl_warn("pipeline vregion still in use");
291+
rfree(alloc);
275292

276293
/* show heap status */
277294
heap_trace_all(0);
@@ -349,8 +366,8 @@ int pipeline_complete(struct pipeline *p, struct comp_dev *source,
349366
p->source_comp = source;
350367
p->sink_comp = sink;
351368

352-
if (p->vreg)
353-
vregion_set_interim(p->vreg);
369+
if (p->alloc && p->alloc->vreg)
370+
vregion_set_interim(p->alloc->vreg);
354371

355372
p->status = COMP_STATE_READY;
356373

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)