Skip to content

Commit 2cd44b0

Browse files
committed
scheduler: dp: fix memory leak / implicit freeing
Task memory was freed implicitly by one DP implementation and was leaked by another one. Free it explicitly for both. Reported-by: Jun Lai <jun.lai@dolby.com> Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
1 parent 74e4191 commit 2cd44b0

File tree

4 files changed

+39
-27
lines changed

4 files changed

+39
-27
lines changed

src/schedule/zephyr_dp_schedule.c

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -295,24 +295,12 @@ static int scheduler_dp_task_free(void *data, struct task *task)
295295
pdata->thread_id = NULL;
296296
}
297297

298-
#ifdef CONFIG_USERSPACE
299-
#if CONFIG_SOF_USERSPACE_PROXY
300-
if (pdata->event != &pdata->event_struct)
301-
k_object_free(pdata->event);
302-
#else
303-
k_object_free(pdata->sem);
304-
#endif
305-
if (pdata->thread != &pdata->thread_struct)
306-
k_object_free(pdata->thread);
307-
#endif
308-
309298
/* free task stack */
310299
ret = user_stack_free(pdata->p_stack);
311300
pdata->p_stack = NULL;
312301

313-
scheduler_dp_domain_free(pdata->mod);
302+
scheduler_dp_internal_free(task);
314303

315-
/* all other memory has been allocated as a single malloc, will be freed later by caller */
316304
return ret;
317305
}
318306

src/schedule/zephyr_dp_schedule.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,4 @@ void scheduler_dp_grant(k_tid_t thread_id, uint16_t core);
5858
int scheduler_dp_task_init(struct task **task, const struct sof_uuid_entry *uid,
5959
const struct task_ops *ops, struct processing_module *mod,
6060
uint16_t core, size_t stack_size, uint32_t options);
61-
#if CONFIG_SOF_USERSPACE_APPLICATION
62-
void scheduler_dp_domain_free(struct processing_module *pmod);
63-
#else
64-
static inline void scheduler_dp_domain_free(struct processing_module *pmod) {}
65-
#endif
61+
void scheduler_dp_internal_free(struct task *task);

src/schedule/zephyr_dp_schedule_application.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ void dp_thread_fn(void *p1, void *p2, void *p3)
383383
* Safe to call with partial successful initialisation,
384384
* k_mem_domain_remove_partition() then just returns -ENOENT
385385
*/
386-
void scheduler_dp_domain_free(struct processing_module *pmod)
386+
static void scheduler_dp_domain_free(struct processing_module *pmod)
387387
{
388388
struct k_mem_domain *mdom = pmod->mdom;
389389

@@ -398,19 +398,32 @@ void scheduler_dp_domain_free(struct processing_module *pmod)
398398
objpool_free(&dp_mdom_head, mdom);
399399
}
400400

401+
/* memory allocation helper structure */
402+
struct scheduler_dp_task_memory {
403+
struct task task;
404+
struct task_dp_pdata pdata;
405+
struct comp_driver drv;
406+
struct ipc4_flat flat;
407+
};
408+
409+
void scheduler_dp_internal_free(struct task *task)
410+
{
411+
struct task_dp_pdata *pdata = task->priv_data;
412+
413+
k_object_free(pdata->sem);
414+
k_object_free(pdata->thread);
415+
mod_free(pdata->mod, container_of(task, struct scheduler_dp_task_memory, task));
416+
417+
scheduler_dp_domain_free(pdata->mod);
418+
}
419+
401420
/* Called only in IPC context */
402421
int scheduler_dp_task_init(struct task **task, const struct sof_uuid_entry *uid,
403422
const struct task_ops *ops, struct processing_module *mod,
404423
uint16_t core, size_t stack_size, uint32_t options)
405424
{
406425
k_thread_stack_t *p_stack;
407-
/* memory allocation helper structure */
408-
struct {
409-
struct task task;
410-
struct task_dp_pdata pdata;
411-
struct comp_driver drv;
412-
struct ipc4_flat flat;
413-
} *task_memory;
426+
struct scheduler_dp_task_memory *task_memory;
414427

415428
int ret;
416429

src/schedule/zephyr_dp_schedule_thread.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ int scheduler_dp_task_init(struct task **task,
187187

188188
/* memory allocation helper structure */
189189
struct {
190-
struct task task;
190+
struct task task; /* keep first, used for freeing below */
191191
struct task_dp_pdata pdata;
192192
} *task_memory;
193193

@@ -308,3 +308,18 @@ int scheduler_dp_task_init(struct task **task,
308308
sof_heap_free(user_heap, task_memory);
309309
return ret;
310310
}
311+
312+
void scheduler_dp_internal_free(struct task *task)
313+
{
314+
struct task_dp_pdata *pdata = task->priv_data;
315+
316+
#ifdef CONFIG_USERSPACE
317+
if (pdata->event != &pdata->event_struct)
318+
k_object_free(pdata->event);
319+
if (pdata->thread != &pdata->thread_struct)
320+
k_object_free(pdata->thread);
321+
#endif
322+
323+
/* task is the first member in task_memory above */
324+
sof_heap_free(pdata->mod->dev->drv->user_heap, task);
325+
}

0 commit comments

Comments
 (0)