From 689e8e999f220356f69b8532216790fed18a9da4 Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Tue, 10 Oct 2023 12:58:54 +0200 Subject: [PATCH] dp: LL tick source start/stop fix as DP uses LL as a tick source, it starts an empty LL task to ensure that an instance of LL is running This applies to mostly to secondary cores, but is may happen that there's no LL instance started on primary This commit fixes 2 problems - LL tick source was stated once for every DP module - LL tick source wasn't stopped when there were no DP modules running anymore Signed-off-by: Marcin Szkudlinski --- src/schedule/zephyr_dp_schedule.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/schedule/zephyr_dp_schedule.c b/src/schedule/zephyr_dp_schedule.c index dae00f632..faa47adcf 100644 --- a/src/schedule/zephyr_dp_schedule.c +++ b/src/schedule/zephyr_dp_schedule.c @@ -30,7 +30,7 @@ DECLARE_TR_CTX(dp_tr, SOF_UUID(dp_sched_uuid), LOG_LEVEL_INFO); struct scheduler_dp_data { struct list_item tasks; /* list of active dp tasks */ - struct task task; /* LL task - source of DP tick */ + struct task ll_tick_src; /* LL task - source of DP tick */ }; struct task_dp_pdata { @@ -254,6 +254,7 @@ void scheduler_dp_ll_tick(void *receiver_data, enum notify_id event_type, void * static int scheduler_dp_task_cancel(void *data, struct task *task) { unsigned int lock_key; + struct scheduler_dp_data *dp_sch = (struct scheduler_dp_data *)data; /* this is asyn cancel - mark the task as canceled and remove it from scheduling */ lock_key = scheduler_dp_lock(); @@ -261,6 +262,10 @@ static int scheduler_dp_task_cancel(void *data, struct task *task) task->state = SOF_TASK_STATE_CANCEL; list_item_del(&task->list); + /* if there're no more DP task, stop LL tick source */ + if (list_is_empty(&dp_sch->tasks)) + schedule_task_cancel(&dp_sch->ll_tick_src); + scheduler_dp_unlock(lock_key); return 0; @@ -268,18 +273,12 @@ static int scheduler_dp_task_cancel(void *data, struct task *task) static int scheduler_dp_task_free(void *data, struct task *task) { - unsigned int lock_key; struct task_dp_pdata *pdata = task->priv_data; + scheduler_dp_task_cancel(data, task); + /* abort the execution of the thread */ k_thread_abort(pdata->thread_id); - - lock_key = scheduler_dp_lock(); - list_item_del(&task->list); - task->priv_data = NULL; - task->state = SOF_TASK_STATE_FREE; - scheduler_dp_unlock(lock_key); - /* free task stack */ rfree((__sparse_force void *)pdata->p_stack); @@ -364,6 +363,10 @@ static int scheduler_dp_task_shedule(void *data, struct task *task, uint64_t sta return -EINVAL; } + /* if there's no DP tasks scheduled yet, run ll tick source task */ + if (list_is_empty(&task->list)) + schedule_task(&dp_sch->ll_tick_src, 0, 0); + /* add a task to DP scheduler list */ task->state = SOF_TASK_STATE_QUEUED; list_item_prepend(&task->list, &dp_sch->tasks); @@ -377,9 +380,6 @@ static int scheduler_dp_task_shedule(void *data, struct task *task, uint64_t sta pdata->period_clock_ticks = period_clock_ticks; scheduler_dp_unlock(lock_key); - /* start LL task - run DP tick start and period are irrelevant for LL (that's bad)*/ - schedule_task(&dp_sch->task, 0, 0); - tr_dbg(&dp_tr, "DP task scheduled with period %u [us]", (uint32_t)period); return 0; } @@ -403,7 +403,7 @@ int scheduler_dp_init(void) scheduler_init(SOF_SCHEDULE_DP, &schedule_dp_ops, dp_sch); /* init src of DP tick */ - ret = schedule_task_init_ll(&dp_sch->task, + ret = schedule_task_init_ll(&dp_sch->ll_tick_src, SOF_UUID(dp_sched_uuid), SOF_SCHEDULE_LL_TIMER, 0, scheduler_dp_ll_tick_dummy, dp_sch,