mirror of https://github.com/thesofproject/sof.git
schedule: cancel a task before freeing it
When a chain DMA stream is the only one running, stopping it currently takes 100ms. The reason is that the chain DMA driver is trying to stop the task directly from the IPC context instead of letting the task exit on its next scheduling event. The IPC thread is indeed trying to wait on a semaphore for the task to exit, but that doesn't work either, because zephyr_domain_unregister() terminates the thread before it signals the semaphore. To fix this we swap the order and signal the semaphore before terminating the thread. Link: https://github.com/thesofproject/sof/issues/8445 Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
This commit is contained in:
parent
3bd9991121
commit
b7d7fb0ed2
|
@ -57,6 +57,8 @@ static void zephyr_ll_assert_core(const struct zephyr_ll *sch)
|
|||
static void zephyr_ll_task_done(struct zephyr_ll *sch,
|
||||
struct task *task)
|
||||
{
|
||||
struct zephyr_ll_pdata *pdata = task->priv_data;
|
||||
|
||||
list_item_del(&task->list);
|
||||
|
||||
if (!sch->n_tasks) {
|
||||
|
@ -66,6 +68,13 @@ static void zephyr_ll_task_done(struct zephyr_ll *sch,
|
|||
|
||||
task->state = SOF_TASK_STATE_FREE;
|
||||
|
||||
if (pdata->freeing)
|
||||
/*
|
||||
* zephyr_ll_task_free() is trying to free this task. Complete
|
||||
* it and signal the semaphore to let the function proceed
|
||||
*/
|
||||
k_sem_give(&pdata->sem);
|
||||
|
||||
tr_info(&ll_tr, "task complete %p %pU", task, task->uid);
|
||||
tr_info(&ll_tr, "num_tasks %d total_num_tasks %ld",
|
||||
sch->n_tasks, atomic_read(&sch->ll_domain->total_num_tasks));
|
||||
|
@ -212,15 +221,7 @@ static void zephyr_ll_run(void *data)
|
|||
|
||||
zephyr_ll_lock(sch, &flags);
|
||||
|
||||
if (pdata->freeing) {
|
||||
/*
|
||||
* zephyr_ll_task_free() is trying to free this task.
|
||||
* complete it and signal the semaphore to let the
|
||||
* function proceed
|
||||
*/
|
||||
zephyr_ll_task_done(sch, task);
|
||||
k_sem_give(&pdata->sem);
|
||||
} else if (state == SOF_TASK_STATE_COMPLETED) {
|
||||
if (pdata->freeing || state == SOF_TASK_STATE_COMPLETED) {
|
||||
zephyr_ll_task_done(sch, task);
|
||||
} else {
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue