@@ -58,24 +58,27 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv,
5858#define PAGE_SZ HOST_PAGE_SIZE
5959#endif
6060
61- static struct k_heap * module_adapter_dp_heap_new (const struct comp_ipc_config * config )
61+ static struct k_heap * module_adapter_dp_heap_new (const struct comp_ipc_config * config ,
62+ size_t * heap_size )
6263{
6364 /* src-lite with 8 channels has been seen allocating 14k in one go */
6465 /* FIXME: the size will be derived from configuration */
65- const size_t heap_size = 20 * 1024 ;
66+ const size_t buf_size = 20 * 1024 ;
6667
6768 /* Keep uncached to match the default SOF heap! */
6869 uint8_t * mod_heap_mem = rballoc_align (SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT ,
69- heap_size , PAGE_SZ );
70+ buf_size , PAGE_SZ );
7071
7172 if (!mod_heap_mem )
7273 return NULL ;
7374
74- struct k_heap * mod_heap = (struct k_heap * )mod_heap_mem ;
75- const size_t heap_prefix_size = ALIGN_UP (sizeof (* mod_heap ), 8 );
75+ struct dp_heap_user * mod_heap_user = (struct dp_heap_user * )mod_heap_mem ;
76+ struct k_heap * mod_heap = & mod_heap_user -> heap ;
77+ const size_t heap_prefix_size = ALIGN_UP (sizeof (* mod_heap_user ), 4 );
7678 void * mod_heap_buf = mod_heap_mem + heap_prefix_size ;
7779
78- k_heap_init (mod_heap , mod_heap_buf , heap_size - heap_prefix_size );
80+ * heap_size = buf_size - heap_prefix_size ;
81+ k_heap_init (mod_heap , mod_heap_buf , * heap_size );
7982
8083 return mod_heap ;
8184}
@@ -93,16 +96,21 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
9396 */
9497 uint32_t flags = config -> proc_domain == COMP_PROCESSING_DOMAIN_DP ?
9598 SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER ;
99+ struct dp_heap_user * mod_heap_user ;
100+ size_t heap_size ;
96101
97102 if (config -> proc_domain == COMP_PROCESSING_DOMAIN_DP && IS_ENABLED (CONFIG_USERSPACE ) &&
98103 !IS_ENABLED (CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP )) {
99- mod_heap = module_adapter_dp_heap_new (config );
104+ mod_heap = module_adapter_dp_heap_new (config , & heap_size );
100105 if (!mod_heap ) {
101106 comp_cl_err (drv , "Failed to allocate DP module heap" );
102107 return NULL ;
103108 }
109+ mod_heap_user = container_of (mod_heap , struct dp_heap_user , heap );
104110 } else {
105111 mod_heap = drv -> user_heap ;
112+ mod_heap_user = NULL ;
113+ heap_size = 0 ;
106114 }
107115
108116 struct processing_module * mod = sof_heap_alloc (mod_heap , flags , sizeof (* mod ), 0 );
@@ -114,6 +122,8 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
114122
115123 memset (mod , 0 , sizeof (* mod ));
116124 mod -> priv .resources .heap = mod_heap ;
125+ mod -> priv .resources .heap_size = heap_size ;
126+ mod_resource_init (mod );
117127
118128 /*
119129 * Would be difficult to optimize the allocation to use cache. Only if
@@ -134,26 +144,37 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
134144 mod -> dev = dev ;
135145 dev -> mod = mod ;
136146
147+ if (mod_heap_user )
148+ mod_heap_user -> client_count ++ ;
149+
137150 return mod ;
138151
139152err :
140153 sof_heap_free (mod_heap , mod );
141154emod :
142- if (mod_heap != drv -> user_heap )
143- rfree (mod_heap );
155+ rfree (mod_heap_user );
144156
145157 return NULL ;
146158}
147159
148160static void module_adapter_mem_free (struct processing_module * mod )
149161{
150162 struct k_heap * mod_heap = mod -> priv .resources .heap ;
163+ struct dp_heap_user * mod_heap_user = CONTAINER_OF (mod_heap , struct dp_heap_user , heap );
151164
165+ /*
166+ * In principle it shouldn't even be needed to free individual objects
167+ * on the module heap since we're freeing the heap itself too
168+ */
152169#if CONFIG_IPC_MAJOR_4
153170 sof_heap_free (mod_heap , mod -> priv .cfg .input_pins );
154171#endif
172+ list_item_del (& mod -> dev -> bsource_list );
173+ list_item_del (& mod -> dev -> bsink_list );
155174 sof_heap_free (mod_heap , mod -> dev );
156175 sof_heap_free (mod_heap , mod );
176+ if (!mod_heap || !-- mod_heap_user -> client_count )
177+ rfree (mod_heap_user );
157178}
158179
159180/*
@@ -1374,11 +1395,16 @@ void module_adapter_free(struct comp_dev *dev)
13741395 comp_dbg (dev , "start" );
13751396
13761397 if (dev -> task ) {
1377- /* Run DP module's .free() method in its thread context */
1398+ /*
1399+ * Run DP module's .free() method in its thread context.
1400+ * Unlike with other IPCs we first run module's .free() in
1401+ * thread context, then cancel the thread, and then execute
1402+ * final clean up
1403+ */
13781404#if CONFIG_IPC_MAJOR_4
13791405 scheduler_dp_thread_ipc (mod , SOF_IPC4_MOD_DELETE_INSTANCE , NULL );
13801406#endif
1381- schedule_task_cancel (dev -> task );
1407+ schedule_task_free (dev -> task );
13821408 }
13831409
13841410 ret = module_free (mod );
0 commit comments