@@ -58,30 +58,33 @@ 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 dp_heap_user * 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#ifdef __ZEPHYR__
8083 mod_heap -> heap .init_mem = mod_heap_buf ;
81- mod_heap -> heap .init_bytes = heap_size - heap_prefix_size ;
84+ mod_heap -> heap .init_bytes = * heap_size ;
8285#endif
8386
84- return mod_heap ;
87+ return mod_heap_user ;
8588}
8689
8790static struct processing_module * module_adapter_mem_alloc (const struct comp_driver * drv ,
@@ -97,16 +100,21 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
97100 */
98101 uint32_t flags = config -> proc_domain == COMP_PROCESSING_DOMAIN_DP ?
99102 SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER ;
103+ struct dp_heap_user * mod_heap_user ;
104+ size_t heap_size ;
100105
101106 if (config -> proc_domain == COMP_PROCESSING_DOMAIN_DP && IS_ENABLED (CONFIG_USERSPACE ) &&
102107 !IS_ENABLED (CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP )) {
103- mod_heap = module_adapter_dp_heap_new (config );
104- if (!mod_heap ) {
108+ mod_heap_user = module_adapter_dp_heap_new (config , & heap_size );
109+ if (!mod_heap_user ) {
105110 comp_cl_err (drv , "Failed to allocate DP module heap" );
106111 return NULL ;
107112 }
113+ mod_heap = & mod_heap_user -> heap ;
108114 } else {
109115 mod_heap = drv -> user_heap ;
116+ mod_heap_user = NULL ;
117+ heap_size = 0 ;
110118 }
111119
112120 struct processing_module * mod = sof_heap_alloc (mod_heap , flags , sizeof (* mod ), 0 );
@@ -118,6 +126,7 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
118126
119127 memset (mod , 0 , sizeof (* mod ));
120128 mod -> priv .resources .heap = mod_heap ;
129+ mod_resource_init (mod );
121130
122131 /*
123132 * Would be difficult to optimize the allocation to use cache. Only if
@@ -138,26 +147,35 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
138147 mod -> dev = dev ;
139148 dev -> mod = mod ;
140149
150+ if (mod_heap_user )
151+ mod_heap_user -> client_count ++ ;
152+
141153 return mod ;
142154
143155err :
144156 sof_heap_free (mod_heap , mod );
145157emod :
146- if (mod_heap != drv -> user_heap )
147- rfree (mod_heap );
158+ rfree (mod_heap_user );
148159
149160 return NULL ;
150161}
151162
152163static void module_adapter_mem_free (struct processing_module * mod )
153164{
154165 struct k_heap * mod_heap = mod -> priv .resources .heap ;
166+ struct dp_heap_user * mod_heap_user = container_of (mod_heap , struct dp_heap_user , heap );
155167
168+ /*
169+ * In principle it shouldn't even be needed to free individual objects
170+ * on the module heap since we're freeing the heap itself too
171+ */
156172#if CONFIG_IPC_MAJOR_4
157173 sof_heap_free (mod_heap , mod -> priv .cfg .input_pins );
158174#endif
159175 sof_heap_free (mod_heap , mod -> dev );
160176 sof_heap_free (mod_heap , mod );
177+ if (!mod_heap || !-- mod_heap_user -> client_count )
178+ rfree (mod_heap_user );
161179}
162180
163181/*
@@ -1378,11 +1396,16 @@ void module_adapter_free(struct comp_dev *dev)
13781396 comp_dbg (dev , "start" );
13791397
13801398 if (dev -> task ) {
1381- /* Run DP module's .free() method in its thread context */
1399+ /*
1400+ * Run DP module's .free() method in its thread context.
1401+ * Unlike with other IPCs we first run module's .free() in
1402+ * thread context, then cancel the thread, and then execute
1403+ * final clean up
1404+ */
13821405#if CONFIG_USERSPACE && !CONFIG_SOF_USERSPACE_PROXY
13831406 scheduler_dp_thread_ipc (mod , SOF_IPC4_MOD_DELETE_INSTANCE , NULL );
13841407#endif
1385- schedule_task_cancel (dev -> task );
1408+ schedule_task_free (dev -> task );
13861409 }
13871410
13881411 ret = module_free (mod );
0 commit comments