@@ -75,23 +75,14 @@ static struct vregion *module_adapter_dp_heap_new(const struct comp_ipc_config *
7575}
7676
7777static
78- struct processing_module * module_adapter_mem_alloc (const struct comp_driver * drv ,
79- const struct comp_ipc_config * config ,
80- const struct module_ext_init_data * ext_init )
78+ struct mod_alloc_ctx * module_adapter_dp_alloc_ctx_new (const struct comp_driver * drv ,
79+ const struct comp_ipc_config * config ,
80+ const struct module_ext_init_data * ext_init ,
81+ uint32_t flags )
8182{
8283 struct k_heap * mod_heap ;
8384 struct vregion * mod_vreg ;
84- struct processing_module * mod ;
85- struct comp_dev * dev ;
86- /*
87- * For DP shared modules the struct processing_module object must be
88- * accessible from all cores. Unfortunately at this point there's no
89- * information of components the module will be bound to. So we need to
90- * allocate shared memory for each DP module.
91- * To be removed when pipeline 2.0 is ready.
92- */
93- uint32_t flags = config -> proc_domain == COMP_PROCESSING_DOMAIN_DP ?
94- SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER ;
85+ struct mod_alloc_ctx * alloc ;
9586
9687 if (config -> proc_domain == COMP_PROCESSING_DOMAIN_DP && IS_ENABLED (CONFIG_SOF_VREGIONS ) &&
9788 IS_ENABLED (CONFIG_USERSPACE ) && !IS_ENABLED (CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP )) {
@@ -114,27 +105,59 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
114105#endif
115106 mod_vreg = NULL ;
116107 }
108+ alloc = sof_heap_alloc (mod_heap , flags , sizeof (* alloc ), 0 );
109+ if (!alloc ) {
110+ comp_cl_err (drv , "sof_alloc_ctx allocation failed" );
111+ vregion_put (mod_vreg );
112+ return NULL ;
113+ }
117114
118- if (!mod_vreg )
119- mod = sof_heap_alloc (mod_heap , flags , sizeof (* mod ), 0 );
120- else if (flags & SOF_MEM_FLAG_COHERENT )
121- mod = vregion_alloc_coherent (mod_vreg , sizeof (* mod ));
122- else
123- mod = vregion_alloc (mod_vreg , sizeof (* mod ));
115+ memset (alloc , 0 , sizeof (* alloc ));
116+ alloc -> heap = mod_heap ;
117+ alloc -> vreg = mod_vreg ;
118+
119+ return alloc ;
120+ }
121+
122+ static
123+ struct processing_module * module_adapter_mem_alloc (const struct comp_driver * drv ,
124+ const struct comp_ipc_config * config ,
125+ const struct module_ext_init_data * ext_init ,
126+ struct mod_alloc_ctx * ppl_alloc )
127+ {
128+ struct processing_module * mod ;
129+ struct mod_alloc_ctx * alloc ;
130+ struct comp_dev * dev ;
131+ /*
132+ * For DP shared modules the struct processing_module object must be
133+ * accessible from all cores. Unfortunately at this point there's no
134+ * information of components the module will be bound to. So we need to
135+ * allocate shared memory for each DP module.
136+ * To be removed when pipeline 2.0 is ready.
137+ */
138+ uint32_t flags = config -> proc_domain == COMP_PROCESSING_DOMAIN_DP ?
139+ SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER ;
140+
141+ if (config -> proc_domain == COMP_PROCESSING_DOMAIN_LL ) {
142+ /* LL modules share the pipeline's alloc context */
143+ alloc = ppl_alloc ;
144+ vregion_get (alloc -> vreg );
145+ } else if (config -> proc_domain == COMP_PROCESSING_DOMAIN_DP ) {
146+ alloc = module_adapter_dp_alloc_ctx_new (drv , config , ext_init , flags );
147+ if (!alloc )
148+ return NULL ;
149+ } else {
150+ comp_cl_err (drv , "bad proc_domain %d" , config -> proc_domain );
151+ return NULL ;
152+ }
124153
154+ mod = sof_ctx_alloc (alloc , flags , sizeof (* mod ), 0 );
125155 if (!mod ) {
126156 comp_cl_err (drv , "failed to allocate memory for module" );
127157 goto emod ;
128158 }
129159
130- struct mod_alloc_ctx * alloc = sof_heap_alloc (mod_heap , flags , sizeof (* alloc ), 0 );
131-
132- if (!alloc )
133- goto ealloc ;
134-
135160 memset (mod , 0 , sizeof (* mod ));
136- alloc -> heap = mod_heap ;
137- alloc -> vreg = mod_vreg ;
138161 mod -> priv .resources .alloc = alloc ;
139162 mod_resource_init (mod );
140163
@@ -144,11 +167,7 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
144167 * then it can be cached. Effectively it can be only cached in
145168 * single-core configurations.
146169 */
147- if (mod_vreg )
148- dev = vregion_alloc_coherent (mod_vreg , sizeof (* dev ));
149- else
150- dev = sof_heap_alloc (mod_heap , SOF_MEM_FLAG_COHERENT , sizeof (* dev ), 0 );
151-
170+ dev = sof_ctx_alloc (alloc , SOF_MEM_FLAG_COHERENT , sizeof (* dev ), 0 );
152171 if (!dev ) {
153172 comp_cl_err (drv , "failed to allocate memory for comp_dev" );
154173 goto edev ;
@@ -163,41 +182,45 @@ struct processing_module *module_adapter_mem_alloc(const struct comp_driver *drv
163182 return mod ;
164183
165184edev :
166- sof_heap_free (mod_heap , alloc );
167- ealloc :
168- if (mod_vreg )
169- vregion_free (mod_vreg , mod );
170- else
171- sof_heap_free (mod_heap , mod );
185+ sof_ctx_free (alloc , mod );
172186emod :
173- vregion_put (mod_vreg );
187+ vregion_put (alloc -> vreg );
188+ if (config -> proc_domain == COMP_PROCESSING_DOMAIN_DP )
189+ sof_heap_free (alloc -> heap , alloc );
174190
175191 return NULL ;
176192}
177193
178194static void module_adapter_mem_free (struct processing_module * mod )
179195{
180196 struct mod_alloc_ctx * alloc = mod -> priv .resources .alloc ;
181- struct k_heap * mod_heap = alloc -> heap ;
197+ bool ppl_alloc = mod -> dev -> ipc_config .proc_domain == COMP_PROCESSING_DOMAIN_LL &&
198+ mod -> dev -> pipeline && mod -> dev -> pipeline -> alloc == alloc ;
182199
183200 /*
184201 * In principle it shouldn't even be needed to free individual objects
185202 * on the module heap since we're freeing the heap itself too
186203 */
187204#if CONFIG_IPC_MAJOR_4
188- sof_heap_free (mod_heap , mod -> priv .cfg .input_pins );
205+ sof_heap_free (alloc -> heap , mod -> priv .cfg .input_pins );
189206#endif
190- if (alloc -> vreg ) {
191- struct vregion * mod_vreg = alloc -> vreg ;
207+ sof_ctx_free (alloc , mod -> dev );
208+ sof_ctx_free ( alloc , mod ) ;
192209
193- vregion_free (mod_vreg , mod -> dev );
194- vregion_free (mod_vreg , mod );
195- if (!vregion_put (mod_vreg ))
210+ if (ppl_alloc ) {
211+ /* alloc belongs to pipeline, just release vregion reference */
212+ vregion_put (alloc -> vreg );
213+ } else if (alloc -> vreg ) {
214+ /*
215+ * This is DP userpsace case
216+ * Only remove the alloc ctx, if vreg was freed. If it was not
217+ * the DP userspace thread is still holding a reference to it,
218+ * and will free alloc ctx eventually.
219+ */
220+ if (!vregion_put (alloc -> vreg ))
196221 sof_heap_free (alloc -> heap , alloc );
197222 } else {
198- sof_heap_free (mod_heap , mod -> dev );
199- sof_heap_free (mod_heap , mod );
200- sof_heap_free (mod_heap , alloc );
223+ sof_heap_free (alloc -> heap , alloc );
201224 }
202225}
203226
@@ -248,8 +271,19 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
248271 NULL ;
249272#endif
250273
251- struct processing_module * mod = module_adapter_mem_alloc (drv , config , ext_init );
274+ struct mod_alloc_ctx * ppl_alloc = NULL ;
275+ #if CONFIG_IPC_MAJOR_4
276+ struct ipc_comp_dev * ipc_pipe ;
277+ struct ipc * ipc = ipc_get ();
252278
279+ /* resolve the pipeline pointer early to pass its alloc to mem_alloc */
280+ ipc_pipe = ipc_get_comp_by_ppl_id (ipc , COMP_TYPE_PIPELINE , config -> pipeline_id ,
281+ IPC_COMP_IGNORE_REMOTE );
282+ if (ipc_pipe && ipc_pipe -> pipeline )
283+ ppl_alloc = ipc_pipe -> pipeline -> alloc ;
284+ #endif
285+
286+ struct processing_module * mod = module_adapter_mem_alloc (drv , config , ext_init , ppl_alloc );
253287 if (!mod )
254288 return NULL ;
255289
@@ -273,6 +307,21 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
273307 dst -> ext_data = & ext_data ;
274308#endif
275309
310+ #if CONFIG_IPC_MAJOR_4
311+ /*
312+ * Set the pipeline pointer if ipc_pipe is valid. Do this
313+ * early so that we can use module_adapter_mem_free() in error
314+ * handling.
315+ */
316+ if (ipc_pipe ) {
317+ dev -> pipeline = ipc_pipe -> pipeline ;
318+
319+ /* LL modules have the same period as the pipeline */
320+ if (dev -> ipc_config .proc_domain == COMP_PROCESSING_DOMAIN_LL )
321+ dev -> period = ipc_pipe -> pipeline -> period ;
322+ }
323+ #endif
324+
276325#if CONFIG_ZEPHYR_DP_SCHEDULER
277326 /* create a task for DP processing */
278327 if (config -> proc_domain == COMP_PROCESSING_DOMAIN_DP ) {
@@ -306,22 +355,6 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
306355 else
307356 goto err ;
308357
309- #if CONFIG_IPC_MAJOR_4
310- struct ipc_comp_dev * ipc_pipe ;
311- struct ipc * ipc = ipc_get ();
312-
313- /* set the pipeline pointer if ipc_pipe is valid */
314- ipc_pipe = ipc_get_comp_by_ppl_id (ipc , COMP_TYPE_PIPELINE , config -> pipeline_id ,
315- IPC_COMP_IGNORE_REMOTE );
316- if (ipc_pipe ) {
317- dev -> pipeline = ipc_pipe -> pipeline ;
318-
319- /* LL modules have the same period as the pipeline */
320- if (dev -> ipc_config .proc_domain == COMP_PROCESSING_DOMAIN_LL )
321- dev -> period = ipc_pipe -> pipeline -> period ;
322- }
323- #endif
324-
325358 /* Init processing module */
326359 ret = module_init (mod );
327360 if (ret ) {
0 commit comments