scheduler: dp: fix memory leak / implicit freeing#10515
scheduler: dp: fix memory leak / implicit freeing#10515kv2019i merged 1 commit intothesofproject:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR centralizes and fixes DP task teardown so that task memory and associated kernel objects are explicitly freed in both DP implementations, eliminating a leak in one path and removing reliance on implicit module-resource cleanup in the other.
Changes:
- Introduces
scheduler_dp_internal_free(struct task *task)as the unified DP task teardown hook, invoked fromscheduler_dp_task_free()inzephyr_dp_schedule.c. - For the kernel-thread DP implementation (
zephyr_dp_schedule_thread.c), documents the task/pdata allocation layout and usesscheduler_dp_internal_free()to free any dynamically allocatedk_objects and the single heap block containingstruct task+struct task_dp_pdata. - For the userspace-application DP implementation (
zephyr_dp_schedule_application.c), factors outscheduler_dp_domain_free()as a file-local helper and ensuresscheduler_dp_internal_free()frees the DP task allocation (viamod_free), its kernel objects, and its memory domain; the header is updated accordingly.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/schedule/zephyr_dp_schedule_thread.c |
Adds a clarified helper allocation layout comment and a scheduler_dp_internal_free() implementation that correctly frees per-task k_objects (when present) and the contiguous DP task allocation from user_heap. |
src/schedule/zephyr_dp_schedule_application.c |
Makes scheduler_dp_domain_free() file-local, introduces a shared scheduler_dp_task_memory struct, and implements scheduler_dp_internal_free() to release semaphore, thread object, DP task memory (via mod_free), and the associated memory domain, with matching error-path cleanup in scheduler_dp_task_init(). |
src/schedule/zephyr_dp_schedule.h |
Replaces the public scheduler_dp_domain_free() declaration (and its non-application stub) with a declaration for the new scheduler_dp_internal_free() teardown helper. |
src/schedule/zephyr_dp_schedule.c |
Switches scheduler_dp_task_free() from inlined conditional cleanup (k_objects + domain) to a single call to scheduler_dp_internal_free(), which now handles the full per-task cleanup including previously leaked allocations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #else | ||
| static inline void scheduler_dp_domain_free(struct processing_module *pmod) {} | ||
| #endif | ||
| void scheduler_dp_internal_free(struct task *task); |
There was a problem hiding this comment.
Could we just change void scheduler_dp_internal_free(struct task *task); as void scheduler_dp_domain_free(struct processing_module *pmod); to force each dp schedule implements their own scheduler_dp_domain_free and avoid introducing a new interface name scheduler_dp_internal_free?
There was a problem hiding this comment.
@checkupup it isn't about just freeing the domain any more, so I preferred to use a new name. It isn't that much of an interface, it's internal to the DP scheduler, so don't think there's an issue with that
| k_object_free(pdata->thread); | ||
| mod_free(pdata->mod, container_of(task, struct scheduler_dp_task_memory, task)); | ||
|
|
||
| scheduler_dp_domain_free(pdata->mod); |
There was a problem hiding this comment.
The scheduler_dp_domain_free function may still access the task pointer, so this call should be moved before the task memory is released.
There was a problem hiding this comment.
@checkupup ah, correct, let me fix that, thanks!
softwarecki
left a comment
There was a problem hiding this comment.
Its a step in the right direction. The LL task cleanup still needs to be addressed.
| struct task_dp_pdata *pdata = task->priv_data; | ||
|
|
||
| k_object_free(pdata->sem); | ||
| k_object_free(pdata->thread); |
There was a problem hiding this comment.
Is if (pdata->thread != &pdata->thread_struct) still needed here?
There was a problem hiding this comment.
No. The "application" variant always creates a thread in userspace and allocates these objects dynamically.
There was a problem hiding this comment.
@checkupup no, it's always the case for the "application" version, it was needed before because the code was covering both versions
| k_object_free(pdata->thread); | ||
| mod_free(pdata->mod, container_of(task, struct scheduler_dp_task_memory, task)); | ||
|
|
||
| scheduler_dp_domain_free(pdata); |
There was a problem hiding this comment.
should be:
scheduler_dp_domain_free(pdata);
mod_free(pdata->mod, container_of(task, struct scheduler_dp_task_memory, task));The memory where pdata resides has been deallocated after calling mod_free.
There was a problem hiding this comment.
@checkupup arrrgh... sure, you're certainly right. Thanks!
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>
lgirdwood
left a comment
There was a problem hiding this comment.
I think all comments have now been addressed. @checkupup is this working for you ?
Looks good for me now. |
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
An alternative implementation of #10512